//
// Copyright (C) 2014-2015 LunarG, Inc.
// Copyright (C) 2015-2020 Google, Inc.
// Copyright (C) 2017 ARM Limited.
// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//    Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//
//    Redistributions in binary form must reproduce the above
//    copyright notice, this list of conditions and the following
//    disclaimer in the documentation and/or other materials provided
//    with the distribution.
//
//    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
//    contributors may be used to endorse or promote products derived
//    from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

//
// "Builder" is an interface to fully build SPIR-V IR.   Allocate one of
// these to build (a thread safe) internal SPIR-V representation (IR),
// and then dump it as a binary stream according to the SPIR-V specification.
//
// A Builder has a 1:1 relationship with a SPIR-V module.
//

#pragma once
#ifndef SpvBuilder_H
#define SpvBuilder_H

#include "Logger.h"
#include "spirv.hpp"
#include "spvIR.h"

#include <algorithm>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <stack>
#include <unordered_map>
#include <map>

namespace spv {

typedef enum {
    Spv_1_0 = (1 << 16),
    Spv_1_1 = (1 << 16) | (1 << 8),
    Spv_1_2 = (1 << 16) | (2 << 8),
    Spv_1_3 = (1 << 16) | (3 << 8),
    Spv_1_4 = (1 << 16) | (4 << 8),
    Spv_1_5 = (1 << 16) | (5 << 8),
} SpvVersion;

class Builder {
public:
    Builder(unsigned int spvVersion, unsigned int userNumber, SpvBuildLogger* logger);
    virtual ~Builder();

    static const int maxMatrixSize = 4;

    unsigned int getSpvVersion() const { return spvVersion; }

    void setSource(spv::SourceLanguage lang, int version)
    {
        source = lang;
        sourceVersion = version;
    }
    spv::Id getStringId(const std::string& str)
    {
        auto sItr = stringIds.find(str);
        if (sItr != stringIds.end())
            return sItr->second;
        spv::Id strId = getUniqueId();
        Instruction* fileString = new Instruction(strId, NoType, OpString);
        const char* file_c_str = str.c_str();
        fileString->addStringOperand(file_c_str);
        strings.push_back(std::unique_ptr<Instruction>(fileString));
        module.mapInstruction(fileString);
        stringIds[file_c_str] = strId;
        return strId;
    }
    void setSourceFile(const std::string& file)
    {
        sourceFileStringId = getStringId(file);
    }
    void setSourceText(const std::string& text) { sourceText = text; }
    void addSourceExtension(const char* ext) { sourceExtensions.push_back(ext); }
    void addModuleProcessed(const std::string& p) { moduleProcesses.push_back(p.c_str()); }
    void setEmitOpLines() { emitOpLines = true; }
    void addExtension(const char* ext) { extensions.insert(ext); }
    void removeExtension(const char* ext)
    {
        extensions.erase(ext);
    }
    void addIncorporatedExtension(const char* ext, SpvVersion incorporatedVersion)
    {
        if (getSpvVersion() < static_cast<unsigned>(incorporatedVersion))
            addExtension(ext);
    }
    void promoteIncorporatedExtension(const char* baseExt, const char* promoExt, SpvVersion incorporatedVersion)
    {
        removeExtension(baseExt);
        addIncorporatedExtension(promoExt, incorporatedVersion);
    }
    void addInclude(const std::string& name, const std::string& text)
    {
        spv::Id incId = getStringId(name);
        includeFiles[incId] = &text;
    }
    Id import(const char*);
    void setMemoryModel(spv::AddressingModel addr, spv::MemoryModel mem)
    {
        addressModel = addr;
        memoryModel = mem;
    }

    void addCapability(spv::Capability cap) { capabilities.insert(cap); }

    // To get a new <id> for anything needing a new one.
    Id getUniqueId() { return ++uniqueId; }

    // To get a set of new <id>s, e.g., for a set of function parameters
    Id getUniqueIds(int numIds)
    {
        Id id = uniqueId + 1;
        uniqueId += numIds;
        return id;
    }

    // Generate OpLine for non-filename-based #line directives (ie no filename
    // seen yet): Log the current line, and if different than the last one,
    // issue a new OpLine using the new line and current source file name.
    void setLine(int line);

    // If filename null, generate OpLine for non-filename-based line directives,
    // else do filename-based: Log the current line and file, and if different
    // than the last one, issue a new OpLine using the new line and file
    // name.
    void setLine(int line, const char* filename);
    // Low-level OpLine. See setLine() for a layered helper.
    void addLine(Id fileName, int line, int column);

    // For creating new types (will return old type if the requested one was already made).
    Id makeVoidType();
    Id makeBoolType();
    Id makePointer(StorageClass, Id pointee);
    Id makeForwardPointer(StorageClass);
    Id makePointerFromForwardPointer(StorageClass, Id forwardPointerType, Id pointee);
    Id makeIntegerType(int width, bool hasSign);   // generic
    Id makeIntType(int width) { return makeIntegerType(width, true); }
    Id makeUintType(int width) { return makeIntegerType(width, false); }
    Id makeFloatType(int width);
    Id makeStructType(const std::vector<Id>& members, const char*);
    Id makeStructResultType(Id type0, Id type1);
    Id makeVectorType(Id component, int size);
    Id makeMatrixType(Id component, int cols, int rows);
    Id makeArrayType(Id element, Id sizeId, int stride);  // 0 stride means no stride decoration
    Id makeRuntimeArray(Id element);
    Id makeFunctionType(Id returnType, const std::vector<Id>& paramTypes);
    Id makeImageType(Id sampledType, Dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format);
    Id makeSamplerType();
    Id makeSampledImageType(Id imageType);
    Id makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols);

    // accelerationStructureNV type
    Id makeAccelerationStructureType();
    // rayQueryEXT type
    Id makeRayQueryType();

    // For querying about types.
    Id getTypeId(Id resultId) const { return module.getTypeId(resultId); }
    Id getDerefTypeId(Id resultId) const;
    Op getOpCode(Id id) const { return module.getInstruction(id)->getOpCode(); }
    Op getTypeClass(Id typeId) const { return getOpCode(typeId); }
    Op getMostBasicTypeClass(Id typeId) const;
    int getNumComponents(Id resultId) const { return getNumTypeComponents(getTypeId(resultId)); }
    int getNumTypeConstituents(Id typeId) const;
    int getNumTypeComponents(Id typeId) const { return getNumTypeConstituents(typeId); }
    Id getScalarTypeId(Id typeId) const;
    Id getContainedTypeId(Id typeId) const;
    Id getContainedTypeId(Id typeId, int) const;
    StorageClass getTypeStorageClass(Id typeId) const { return module.getStorageClass(typeId); }
    ImageFormat getImageTypeFormat(Id typeId) const
        { return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6); }

    bool isPointer(Id resultId)      const { return isPointerType(getTypeId(resultId)); }
    bool isScalar(Id resultId)       const { return isScalarType(getTypeId(resultId)); }
    bool isVector(Id resultId)       const { return isVectorType(getTypeId(resultId)); }
    bool isMatrix(Id resultId)       const { return isMatrixType(getTypeId(resultId)); }
    bool isCooperativeMatrix(Id resultId)const { return isCooperativeMatrixType(getTypeId(resultId)); }
    bool isAggregate(Id resultId)    const { return isAggregateType(getTypeId(resultId)); }
    bool isSampledImage(Id resultId) const { return isSampledImageType(getTypeId(resultId)); }

    bool isBoolType(Id typeId)
        { return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); }
    bool isIntType(Id typeId)          const
        { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) != 0; }
    bool isUintType(Id typeId)         const
        { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) == 0; }
    bool isFloatType(Id typeId)        const { return getTypeClass(typeId) == OpTypeFloat; }
    bool isPointerType(Id typeId)      const { return getTypeClass(typeId) == OpTypePointer; }
    bool isScalarType(Id typeId)       const
        { return getTypeClass(typeId) == OpTypeFloat || getTypeClass(typeId) == OpTypeInt ||
          getTypeClass(typeId) == OpTypeBool; }
    bool isVectorType(Id typeId)       const { return getTypeClass(typeId) == OpTypeVector; }
    bool isMatrixType(Id typeId)       const { return getTypeClass(typeId) == OpTypeMatrix; }
    bool isStructType(Id typeId)       const { return getTypeClass(typeId) == OpTypeStruct; }
    bool isArrayType(Id typeId)        const { return getTypeClass(typeId) == OpTypeArray; }
#ifdef GLSLANG_WEB
    bool isCooperativeMatrixType(Id typeId)const { return false; }
#else
    bool isCooperativeMatrixType(Id typeId)const { return getTypeClass(typeId) == OpTypeCooperativeMatrixNV; }
#endif
    bool isAggregateType(Id typeId)    const
        { return isArrayType(typeId) || isStructType(typeId) || isCooperativeMatrixType(typeId); }
    bool isImageType(Id typeId)        const { return getTypeClass(typeId) == OpTypeImage; }
    bool isSamplerType(Id typeId)      const { return getTypeClass(typeId) == OpTypeSampler; }
    bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; }
    bool containsType(Id typeId, Op typeOp, unsigned int width) const;
    bool containsPhysicalStorageBufferOrArray(Id typeId) const;

    bool isConstantOpCode(Op opcode) const;
    bool isSpecConstantOpCode(Op opcode) const;
    bool isConstant(Id resultId) const { return isConstantOpCode(getOpCode(resultId)); }
    bool isConstantScalar(Id resultId) const { return getOpCode(resultId) == OpConstant; }
    bool isSpecConstant(Id resultId) const { return isSpecConstantOpCode(getOpCode(resultId)); }
    unsigned int getConstantScalar(Id resultId) const
        { return module.getInstruction(resultId)->getImmediateOperand(0); }
    StorageClass getStorageClass(Id resultId) const { return getTypeStorageClass(getTypeId(resultId)); }

    bool isVariableOpCode(Op opcode) const { return opcode == OpVariable; }
    bool isVariable(Id resultId) const { return isVariableOpCode(getOpCode(resultId)); }
    bool isGlobalStorage(Id resultId) const { return getStorageClass(resultId) != StorageClassFunction; }
    bool isGlobalVariable(Id resultId) const { return isVariable(resultId) && isGlobalStorage(resultId); }
    // See if a resultId is valid for use as an initializer.
    bool isValidInitializer(Id resultId) const { return isConstant(resultId) || isGlobalVariable(resultId); }

    int getScalarTypeWidth(Id typeId) const
    {
        Id scalarTypeId = getScalarTypeId(typeId);
        assert(getTypeClass(scalarTypeId) == OpTypeInt || getTypeClass(scalarTypeId) == OpTypeFloat);
        return module.getInstruction(scalarTypeId)->getImmediateOperand(0);
    }

    int getTypeNumColumns(Id typeId) const
    {
        assert(isMatrixType(typeId));
        return getNumTypeConstituents(typeId);
    }
    int getNumColumns(Id resultId) const { return getTypeNumColumns(getTypeId(resultId)); }
    int getTypeNumRows(Id typeId) const
    {
        assert(isMatrixType(typeId));
        return getNumTypeComponents(getContainedTypeId(typeId));
    }
    int getNumRows(Id resultId) const { return getTypeNumRows(getTypeId(resultId)); }

    Dim getTypeDimensionality(Id typeId) const
    {
        assert(isImageType(typeId));
        return (Dim)module.getInstruction(typeId)->getImmediateOperand(1);
    }
    Id getImageType(Id resultId) const
    {
        Id typeId = getTypeId(resultId);
        assert(isImageType(typeId) || isSampledImageType(typeId));
        return isSampledImageType(typeId) ? module.getInstruction(typeId)->getIdOperand(0) : typeId;
    }
    bool isArrayedImageType(Id typeId) const
    {
        assert(isImageType(typeId));
        return module.getInstruction(typeId)->getImmediateOperand(3) != 0;
    }

    // For making new constants (will return old constant if the requested one was already made).
    Id makeNullConstant(Id typeId);
    Id makeBoolConstant(bool b, bool specConstant = false);
    Id makeInt8Constant(int i, bool specConstant = false)
        { return makeIntConstant(makeIntType(8),  (unsigned)i, specConstant); }
    Id makeUint8Constant(unsigned u, bool specConstant = false)
        { return makeIntConstant(makeUintType(8),           u, specConstant); }
    Id makeInt16Constant(int i, bool specConstant = false)
        { return makeIntConstant(makeIntType(16),  (unsigned)i, specConstant); }
    Id makeUint16Constant(unsigned u, bool specConstant = false)
        { return makeIntConstant(makeUintType(16),           u, specConstant); }
    Id makeIntConstant(int i, bool specConstant = false)
        { return makeIntConstant(makeIntType(32),  (unsigned)i, specConstant); }
    Id makeUintConstant(unsigned u, bool specConstant = false)
        { return makeIntConstant(makeUintType(32),           u, specConstant); }
    Id makeInt64Constant(long long i, bool specConstant = false)
        { return makeInt64Constant(makeIntType(64),  (unsigned long long)i, specConstant); }
    Id makeUint64Constant(unsigned long long u, bool specConstant = false)
        { return makeInt64Constant(makeUintType(64),                     u, specConstant); }
    Id makeFloatConstant(float f, bool specConstant = false);
    Id makeDoubleConstant(double d, bool specConstant = false);
    Id makeFloat16Constant(float f16, bool specConstant = false);
    Id makeFpConstant(Id type, double d, bool specConstant = false);

    // Turn the array of constants into a proper spv constant of the requested type.
    Id makeCompositeConstant(Id type, const std::vector<Id>& comps, bool specConst = false);

    // Methods for adding information outside the CFG.
    Instruction* addEntryPoint(ExecutionModel, Function*, const char* name);
    void addExecutionMode(Function*, ExecutionMode mode, int value1 = -1, int value2 = -1, int value3 = -1);
    void addExecutionMode(Function*, ExecutionMode mode, const std::vector<unsigned>& literals);
    void addExecutionModeId(Function*, ExecutionMode mode, const std::vector<Id>& operandIds);
    void addName(Id, const char* name);
    void addMemberName(Id, int member, const char* name);
    void addDecoration(Id, Decoration, int num = -1);
    void addDecoration(Id, Decoration, const char*);
    void addDecoration(Id, Decoration, const std::vector<unsigned>& literals);
    void addDecoration(Id, Decoration, const std::vector<const char*>& strings);
    void addDecorationId(Id id, Decoration, Id idDecoration);
    void addDecorationId(Id id, Decoration, const std::vector<Id>& operandIds);
    void addMemberDecoration(Id, unsigned int member, Decoration, int num = -1);
    void addMemberDecoration(Id, unsigned int member, Decoration, const char*);
    void addMemberDecoration(Id, unsigned int member, Decoration, const std::vector<unsigned>& literals);
    void addMemberDecoration(Id, unsigned int member, Decoration, const std::vector<const char*>& strings);

    // At the end of what block do the next create*() instructions go?
    void setBuildPoint(Block* bp) { buildPoint = bp; }
    Block* getBuildPoint() const { return buildPoint; }

    // Make the entry-point function. The returned pointer is only valid
    // for the lifetime of this builder.
    Function* makeEntryPoint(const char*);

    // Make a shader-style function, and create its entry block if entry is non-zero.
    // Return the function, pass back the entry.
    // The returned pointer is only valid for the lifetime of this builder.
    Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name,
        const std::vector<Id>& paramTypes, const std::vector<std::vector<Decoration>>& precisions, Block **entry = 0);

    // Create a return. An 'implicit' return is one not appearing in the source
    // code.  In the case of an implicit return, no post-return block is inserted.
    void makeReturn(bool implicit, Id retVal = 0);

    // Generate all the code needed to finish up a function.
    void leaveFunction();

    // Create block terminator instruction for certain statements like
    // discard, terminate-invocation, terminateRayEXT, or ignoreIntersectionEXT
    void makeStatementTerminator(spv::Op opcode, const char *name);

    // Create a global or function local or IO variable.
    Id createVariable(Decoration precision, StorageClass, Id type, const char* name = nullptr,
        Id initializer = NoResult);

    // Create an intermediate with an undefined value.
    Id createUndefined(Id type);

    // Store into an Id and return the l-value
    void createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone,
        spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);

    // Load from an Id and return it
    Id createLoad(Id lValue, spv::Decoration precision,
        spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone,
        spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);

    // Create an OpAccessChain instruction
    Id createAccessChain(StorageClass, Id base, const std::vector<Id>& offsets);

    // Create an OpArrayLength instruction
    Id createArrayLength(Id base, unsigned int member);

    // Create an OpCooperativeMatrixLengthNV instruction
    Id createCooperativeMatrixLength(Id type);

    // Create an OpCompositeExtract instruction
    Id createCompositeExtract(Id composite, Id typeId, unsigned index);
    Id createCompositeExtract(Id composite, Id typeId, const std::vector<unsigned>& indexes);
    Id createCompositeInsert(Id object, Id composite, Id typeId, unsigned index);
    Id createCompositeInsert(Id object, Id composite, Id typeId, const std::vector<unsigned>& indexes);

    Id createVectorExtractDynamic(Id vector, Id typeId, Id componentIndex);
    Id createVectorInsertDynamic(Id vector, Id typeId, Id component, Id componentIndex);

    void createNoResultOp(Op);
    void createNoResultOp(Op, Id operand);
    void createNoResultOp(Op, const std::vector<Id>& operands);
    void createNoResultOp(Op, const std::vector<IdImmediate>& operands);
    void createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask);
    void createMemoryBarrier(unsigned executionScope, unsigned memorySemantics);
    Id createUnaryOp(Op, Id typeId, Id operand);
    Id createBinOp(Op, Id typeId, Id operand1, Id operand2);
    Id createTriOp(Op, Id typeId, Id operand1, Id operand2, Id operand3);
    Id createOp(Op, Id typeId, const std::vector<Id>& operands);
    Id createOp(Op, Id typeId, const std::vector<IdImmediate>& operands);
    Id createFunctionCall(spv::Function*, const std::vector<spv::Id>&);
    Id createSpecConstantOp(Op, Id typeId, const std::vector<spv::Id>& operands, const std::vector<unsigned>& literals);

    // Take an rvalue (source) and a set of channels to extract from it to
    // make a new rvalue, which is returned.
    Id createRvalueSwizzle(Decoration precision, Id typeId, Id source, const std::vector<unsigned>& channels);

    // Take a copy of an lvalue (target) and a source of components, and set the
    // source components into the lvalue where the 'channels' say to put them.
    // An updated version of the target is returned.
    // (No true lvalue or stores are used.)
    Id createLvalueSwizzle(Id typeId, Id target, Id source, const std::vector<unsigned>& channels);

    // If both the id and precision are valid, the id
    // gets tagged with the requested precision.
    // The passed in id is always the returned id, to simplify use patterns.
    Id setPrecision(Id id, Decoration precision)
    {
        if (precision != NoPrecision && id != NoResult)
            addDecoration(id, precision);

        return id;
    }

    // Can smear a scalar to a vector for the following forms:
    //   - promoteScalar(scalar, vector)  // smear scalar to width of vector
    //   - promoteScalar(vector, scalar)  // smear scalar to width of vector
    //   - promoteScalar(pointer, scalar) // smear scalar to width of what pointer points to
    //   - promoteScalar(scalar, scalar)  // do nothing
    // Other forms are not allowed.
    //
    // Generally, the type of 'scalar' does not need to be the same type as the components in 'vector'.
    // The type of the created vector is a vector of components of the same type as the scalar.
    //
    // Note: One of the arguments will change, with the result coming back that way rather than
    // through the return value.
    void promoteScalar(Decoration precision, Id& left, Id& right);

    // Make a value by smearing the scalar to fill the type.
    // vectorType should be the correct type for making a vector of scalarVal.
    // (No conversions are done.)
    Id smearScalar(Decoration precision, Id scalarVal, Id vectorType);

    // Create a call to a built-in function.
    Id createBuiltinCall(Id resultType, Id builtins, int entryPoint, const std::vector<Id>& args);

    // List of parameters used to create a texture operation
    struct TextureParameters {
        Id sampler;
        Id coords;
        Id bias;
        Id lod;
        Id Dref;
        Id offset;
        Id offsets;
        Id gradX;
        Id gradY;
        Id sample;
        Id component;
        Id texelOut;
        Id lodClamp;
        Id granularity;
        Id coarse;
        bool nonprivate;
        bool volatil;
    };

    // Select the correct texture operation based on all inputs, and emit the correct instruction
    Id createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather,
        bool noImplicit, const TextureParameters&, ImageOperandsMask);

    // Emit the OpTextureQuery* instruction that was passed in.
    // Figure out the right return value and type, and return it.
    Id createTextureQueryCall(Op, const TextureParameters&, bool isUnsignedResult);

    Id createSamplePositionCall(Decoration precision, Id, Id);

    Id createBitFieldExtractCall(Decoration precision, Id, Id, Id, bool isSigned);
    Id createBitFieldInsertCall(Decoration precision, Id, Id, Id, Id);

    // Reduction comparison for composites:  For equal and not-equal resulting in a scalar.
    Id createCompositeCompare(Decoration precision, Id, Id, bool /* true if for equal, false if for not-equal */);

    // OpCompositeConstruct
    Id createCompositeConstruct(Id typeId, const std::vector<Id>& constituents);

    // vector or scalar constructor
    Id createConstructor(Decoration precision, const std::vector<Id>& sources, Id resultTypeId);

    // matrix constructor
    Id createMatrixConstructor(Decoration precision, const std::vector<Id>& sources, Id constructee);

    // Helper to use for building nested control flow with if-then-else.
    class If {
    public:
        If(Id condition, unsigned int ctrl, Builder& builder);
        ~If() {}

        void makeBeginElse();
        void makeEndIf();

    private:
        If(const If&);
        If& operator=(If&);

        Builder& builder;
        Id condition;
        unsigned int control;
        Function* function;
        Block* headerBlock;
        Block* thenBlock;
        Block* elseBlock;
        Block* mergeBlock;
    };

    // Make a switch statement.  A switch has 'numSegments' of pieces of code, not containing
    // any case/default labels, all separated by one or more case/default labels.  Each possible
    // case value v is a jump to the caseValues[v] segment.  The defaultSegment is also in this
    // number space.  How to compute the value is given by 'condition', as in switch(condition).
    //
    // The SPIR-V Builder will maintain the stack of post-switch merge blocks for nested switches.
    //
    // Use a defaultSegment < 0 if there is no default segment (to branch to post switch).
    //
    // Returns the right set of basic blocks to start each code segment with, so that the caller's
    // recursion stack can hold the memory for it.
    //
    void makeSwitch(Id condition, unsigned int control, int numSegments, const std::vector<int>& caseValues,
                    const std::vector<int>& valueToSegment, int defaultSegment, std::vector<Block*>& segmentBB);

    // Add a branch to the innermost switch's merge block.
    void addSwitchBreak();

    // Move to the next code segment, passing in the return argument in makeSwitch()
    void nextSwitchSegment(std::vector<Block*>& segmentBB, int segment);

    // Finish off the innermost switch.
    void endSwitch(std::vector<Block*>& segmentBB);

    struct LoopBlocks {
        LoopBlocks(Block& head, Block& body, Block& merge, Block& continue_target) :
            head(head), body(body), merge(merge), continue_target(continue_target) { }
        Block &head, &body, &merge, &continue_target;
    private:
        LoopBlocks();
        LoopBlocks& operator=(const LoopBlocks&) = delete;
    };

    // Start a new loop and prepare the builder to generate code for it.  Until
    // closeLoop() is called for this loop, createLoopContinue() and
    // createLoopExit() will target its corresponding blocks.
    LoopBlocks& makeNewLoop();

    // Create a new block in the function containing the build point.  Memory is
    // owned by the function object.
    Block& makeNewBlock();

    // Add a branch to the continue_target of the current (innermost) loop.
    void createLoopContinue();

    // Add an exit (e.g. "break") from the innermost loop that we're currently
    // in.
    void createLoopExit();

    // Close the innermost loop that you're in
    void closeLoop();

    //
    // Access chain design for an R-Value vs. L-Value:
    //
    // There is a single access chain the builder is building at
    // any particular time.  Such a chain can be used to either to a load or
    // a store, when desired.
    //
    // Expressions can be r-values, l-values, or both, or only r-values:
    //    a[b.c].d = ....  // l-value
    //    ... = a[b.c].d;  // r-value, that also looks like an l-value
    //    ++a[b.c].d;      // r-value and l-value
    //    (x + y)[2];      // r-value only, can't possibly be l-value
    //
    // Computing an r-value means generating code.  Hence,
    // r-values should only be computed when they are needed, not speculatively.
    //
    // Computing an l-value means saving away information for later use in the compiler,
    // no code is generated until the l-value is later dereferenced.  It is okay
    // to speculatively generate an l-value, just not okay to speculatively dereference it.
    //
    // The base of the access chain (the left-most variable or expression
    // from which everything is based) can be set either as an l-value
    // or as an r-value.  Most efficient would be to set an l-value if one
    // is available.  If an expression was evaluated, the resulting r-value
    // can be set as the chain base.
    //
    // The users of this single access chain can save and restore if they
    // want to nest or manage multiple chains.
    //

    struct AccessChain {
        Id base;                       // for l-values, pointer to the base object, for r-values, the base object
        std::vector<Id> indexChain;
        Id instr;                      // cache the instruction that generates this access chain
        std::vector<unsigned> swizzle; // each std::vector element selects the next GLSL component number
        Id component;                  // a dynamic component index, can coexist with a swizzle,
                                       // done after the swizzle, NoResult if not present
        Id preSwizzleBaseType;         // dereferenced type, before swizzle or component is applied;
                                       // NoType unless a swizzle or component is present
        bool isRValue;                 // true if 'base' is an r-value, otherwise, base is an l-value
        unsigned int alignment;        // bitwise OR of alignment values passed in. Accumulates worst alignment.
                                       // Only tracks base and (optional) component selection alignment.

        // Accumulate whether anything in the chain of structures has coherent decorations.
        struct CoherentFlags {
            CoherentFlags() { clear(); }
#ifdef GLSLANG_WEB
            void clear() { }
            bool isVolatile() const { return false; }
            CoherentFlags operator |=(const CoherentFlags &other) { return *this; }
#else
            bool isVolatile() const { return volatil; }
            bool isNonUniform() const { return nonUniform; }
            bool anyCoherent() const {
                return coherent || devicecoherent || queuefamilycoherent || workgroupcoherent ||
                    subgroupcoherent || shadercallcoherent;
            }

            unsigned coherent : 1;
            unsigned devicecoherent : 1;
            unsigned queuefamilycoherent : 1;
            unsigned workgroupcoherent : 1;
            unsigned subgroupcoherent : 1;
            unsigned shadercallcoherent : 1;
            unsigned nonprivate : 1;
            unsigned volatil : 1;
            unsigned isImage : 1;
            unsigned nonUniform : 1;

            void clear() {
                coherent = 0;
                devicecoherent = 0;
                queuefamilycoherent = 0;
                workgroupcoherent = 0;
                subgroupcoherent = 0;
                shadercallcoherent = 0;
                nonprivate = 0;
                volatil = 0;
                isImage = 0;
                nonUniform = 0;
            }

            CoherentFlags operator |=(const CoherentFlags &other) {
                coherent |= other.coherent;
                devicecoherent |= other.devicecoherent;
                queuefamilycoherent |= other.queuefamilycoherent;
                workgroupcoherent |= other.workgroupcoherent;
                subgroupcoherent |= other.subgroupcoherent;
                shadercallcoherent |= other.shadercallcoherent;
                nonprivate |= other.nonprivate;
                volatil |= other.volatil;
                isImage |= other.isImage;
                nonUniform |= other.nonUniform;
                return *this;
            }
#endif
        };
        CoherentFlags coherentFlags;
    };

    //
    // the SPIR-V builder maintains a single active chain that
    // the following methods operate on
    //

    // for external save and restore
    AccessChain getAccessChain() { return accessChain; }
    void setAccessChain(AccessChain newChain) { accessChain = newChain; }

    // clear accessChain
    void clearAccessChain();

    // set new base as an l-value base
    void setAccessChainLValue(Id lValue)
    {
        assert(isPointer(lValue));
        accessChain.base = lValue;
    }

    // set new base value as an r-value
    void setAccessChainRValue(Id rValue)
    {
        accessChain.isRValue = true;
        accessChain.base = rValue;
    }

    // push offset onto the end of the chain
    void accessChainPush(Id offset, AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
    {
        accessChain.indexChain.push_back(offset);
        accessChain.coherentFlags |= coherentFlags;
        accessChain.alignment |= alignment;
    }

    // push new swizzle onto the end of any existing swizzle, merging into a single swizzle
    void accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType,
        AccessChain::CoherentFlags coherentFlags, unsigned int alignment);

    // push a dynamic component selection onto the access chain, only applicable with a
    // non-trivial swizzle or no swizzle
    void accessChainPushComponent(Id component, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags,
        unsigned int alignment)
    {
        if (accessChain.swizzle.size() != 1) {
            accessChain.component = component;
            if (accessChain.preSwizzleBaseType == NoType)
                accessChain.preSwizzleBaseType = preSwizzleBaseType;
        }
        accessChain.coherentFlags |= coherentFlags;
        accessChain.alignment |= alignment;
    }

    // use accessChain and swizzle to store value
    void accessChainStore(Id rvalue, Decoration nonUniform,
        spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone,
        spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);

    // use accessChain and swizzle to load an r-value
    Id accessChainLoad(Decoration precision, Decoration l_nonUniform, Decoration r_nonUniform, Id ResultType,
        spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax,
            unsigned int alignment = 0);

    // Return whether or not the access chain can be represented in SPIR-V
    // as an l-value.
    // E.g., a[3].yx cannot be, while a[3].y and a[3].y[x] can be.
    bool isSpvLvalue() const { return accessChain.swizzle.size() <= 1; }

    // get the direct pointer for an l-value
    Id accessChainGetLValue();

    // Get the inferred SPIR-V type of the result of the current access chain,
    // based on the type of the base and the chain of dereferences.
    Id accessChainGetInferredType();

    // Add capabilities, extensions, remove unneeded decorations, etc.,
    // based on the resulting SPIR-V.
    void postProcess();

    // Prune unreachable blocks in the CFG and remove unneeded decorations.
    void postProcessCFG();

#ifndef GLSLANG_WEB
    // Add capabilities, extensions based on instructions in the module.
    void postProcessFeatures();
    // Hook to visit each instruction in a block in a function
    void postProcess(Instruction&);
    // Hook to visit each non-32-bit sized float/int operation in a block.
    void postProcessType(const Instruction&, spv::Id typeId);
#endif

    void dump(std::vector<unsigned int>&) const;

    void createBranch(Block* block);
    void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);
    void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control,
        const std::vector<unsigned int>& operands);

    // Sets to generate opcode for specialization constants.
    void setToSpecConstCodeGenMode() { generatingOpCodeForSpecConst = true; }
    // Sets to generate opcode for non-specialization constants (normal mode).
    void setToNormalCodeGenMode() { generatingOpCodeForSpecConst = false; }
    // Check if the builder is generating code for spec constants.
    bool isInSpecConstCodeGenMode() { return generatingOpCodeForSpecConst; }

 protected:
    Id makeIntConstant(Id typeId, unsigned value, bool specConstant);
    Id makeInt64Constant(Id typeId, unsigned long long value, bool specConstant);
    Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value);
    Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2);
    Id findCompositeConstant(Op typeClass, Id typeId, const std::vector<Id>& comps);
    Id findStructConstant(Id typeId, const std::vector<Id>& comps);
    Id collapseAccessChain();
    void remapDynamicSwizzle();
    void transferAccessChainSwizzle(bool dynamic);
    void simplifyAccessChainSwizzle();
    void createAndSetNoPredecessorBlock(const char*);
    void createSelectionMerge(Block* mergeBlock, unsigned int control);
    void dumpSourceInstructions(std::vector<unsigned int>&) const;
    void dumpSourceInstructions(const spv::Id fileId, const std::string& text, std::vector<unsigned int>&) const;
    void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
    void dumpModuleProcesses(std::vector<unsigned int>&) const;
    spv::MemoryAccessMask sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc)
        const;

    unsigned int spvVersion;     // the version of SPIR-V to emit in the header
    SourceLanguage source;
    int sourceVersion;
    spv::Id sourceFileStringId;
    std::string sourceText;
    int currentLine;
    const char* currentFile;
    bool emitOpLines;
    std::set<std::string> extensions;
    std::vector<const char*> sourceExtensions;
    std::vector<const char*> moduleProcesses;
    AddressingModel addressModel;
    MemoryModel memoryModel;
    std::set<spv::Capability> capabilities;
    int builderNumber;
    Module module;
    Block* buildPoint;
    Id uniqueId;
    Function* entryPointFunction;
    bool generatingOpCodeForSpecConst;
    AccessChain accessChain;

    // special blocks of instructions for output
    std::vector<std::unique_ptr<Instruction> > strings;
    std::vector<std::unique_ptr<Instruction> > imports;
    std::vector<std::unique_ptr<Instruction> > entryPoints;
    std::vector<std::unique_ptr<Instruction> > executionModes;
    std::vector<std::unique_ptr<Instruction> > names;
    std::vector<std::unique_ptr<Instruction> > decorations;
    std::vector<std::unique_ptr<Instruction> > constantsTypesGlobals;
    std::vector<std::unique_ptr<Instruction> > externals;
    std::vector<std::unique_ptr<Function> > functions;

    // not output, internally used for quick & dirty canonical (unique) creation

    // map type opcodes to constant inst.
    std::unordered_map<unsigned int, std::vector<Instruction*>> groupedConstants;
    // map struct-id to constant instructions
    std::unordered_map<unsigned int, std::vector<Instruction*>> groupedStructConstants;
    // map type opcodes to type instructions
    std::unordered_map<unsigned int, std::vector<Instruction*>> groupedTypes;
    // list of OpConstantNull instructions
    std::vector<Instruction*> nullConstants;

    // stack of switches
    std::stack<Block*> switchMerges;

    // Our loop stack.
    std::stack<LoopBlocks> loops;

    // map from strings to their string ids
    std::unordered_map<std::string, spv::Id> stringIds;

    // map from include file name ids to their contents
    std::map<spv::Id, const std::string*> includeFiles;

    // The stream for outputting warnings and errors.
    SpvBuildLogger* logger;
};  // end Builder class

};  // end spv namespace

#endif // SpvBuilder_H
