//
//Copyright (C) 2015 LunarG, Inc.
//
//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.
//

#ifndef SPIRVREMAPPER_H
#define SPIRVREMAPPER_H

#include <string>
#include <vector>
#include <cstdlib>

namespace spv {

// MSVC defines __cplusplus as an older value, even when it supports almost all of 11.
// We handle that here by making our own symbol.
#if __cplusplus >= 201103L || _MSC_VER >= 1700
#   define use_cpp11 1
#endif

class spirvbin_base_t
{
public:
   enum Options {
      NONE          = 0,
      STRIP         = (1<<0),
      MAP_TYPES     = (1<<1),
      MAP_NAMES     = (1<<2),
      MAP_FUNCS     = (1<<3),
      DCE_FUNCS     = (1<<4),
      DCE_VARS      = (1<<5),
      DCE_TYPES     = (1<<6),
      OPT_LOADSTORE = (1<<7),
      OPT_FWD_LS    = (1<<8), // EXPERIMENTAL: PRODUCES INVALID SCHEMA-0 SPIRV
      MAP_ALL       = (MAP_TYPES | MAP_NAMES | MAP_FUNCS),
      DCE_ALL       = (DCE_FUNCS | DCE_VARS | DCE_TYPES),
      OPT_ALL       = (OPT_LOADSTORE),

      ALL_BUT_STRIP = (MAP_ALL | DCE_ALL | OPT_ALL),
      DO_EVERYTHING = (STRIP | ALL_BUT_STRIP)
   };
};

} // namespace SPV

#if !defined (use_cpp11)
#include <cstdio>
#include <cstdint>

namespace spv {
class spirvbin_t : public spirvbin_base_t
{
public:
    spirvbin_t(int /*verbose = 0*/) { }

    void remap(std::vector<std::uint32_t>& /*spv*/, unsigned int /*opts = 0*/)
    {
        printf("Tool not compiled for C++11, which is required for SPIR-V remapping.\n");
        exit(5);
    }
};

} // namespace SPV

#else // defined (use_cpp11)

#include <functional>
#include <cstdint>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <set>
#include <cassert>

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

namespace spv {

// class to hold SPIR-V binary data for remapping, DCE, and debug stripping
class spirvbin_t : public spirvbin_base_t
{
public:
   spirvbin_t(int verbose = 0) : entryPoint(spv::NoResult), largestNewId(0), verbose(verbose) { }
   
   // remap on an existing binary in memory
   void remap(std::vector<std::uint32_t>& spv, std::uint32_t opts = DO_EVERYTHING);

   // Type for error/log handler functions
   typedef std::function<void(const std::string&)> errorfn_t;
   typedef std::function<void(const std::string&)> logfn_t;

   // Register error/log handling functions (can be lambda fn / functor / etc)
   static void registerErrorHandler(errorfn_t handler) { errorHandler = handler; }
   static void registerLogHandler(logfn_t handler)     { logHandler   = handler; }

protected:
   // This can be overridden to provide other message behavior if needed
   virtual void msg(int minVerbosity, int indent, const std::string& txt) const;

private:
   // Local to global, or global to local ID map
   typedef std::unordered_map<spv::Id, spv::Id> idmap_t;
   typedef std::unordered_set<spv::Id>          idset_t;
   typedef std::unordered_map<spv::Id, int>     blockmap_t;

   void remap(std::uint32_t opts = DO_EVERYTHING);

   // Map of names to IDs
   typedef std::unordered_map<std::string, spv::Id> namemap_t;

   typedef std::uint32_t spirword_t;

   typedef std::pair<unsigned, unsigned> range_t;
   typedef std::function<void(spv::Id&)>                idfn_t;
   typedef std::function<bool(spv::Op, unsigned start)> instfn_t;

   // Special Values for ID map:
   static const spv::Id unmapped;     // unchanged from default value
   static const spv::Id unused;       // unused ID
   static const int     header_size;  // SPIR header = 5 words

   class id_iterator_t;

   // For mapping type entries between different shaders
   typedef std::vector<spirword_t>        typeentry_t;
   typedef std::map<spv::Id, typeentry_t> globaltypes_t;

   // A set that preserves position order, and a reverse map
   typedef std::set<int>                    posmap_t;
   typedef std::unordered_map<spv::Id, int> posmap_rev_t;

   // Maps and ID to the size of its base type, if known.
   typedef std::unordered_map<spv::Id, unsigned> typesize_map_t;

   // handle error
   void error(const std::string& txt) const { errorHandler(txt); }

   bool     isConstOp(spv::Op opCode)      const;
   bool     isTypeOp(spv::Op opCode)       const;
   bool     isStripOp(spv::Op opCode)      const;
   bool     isFlowCtrl(spv::Op opCode)     const;
   range_t  literalRange(spv::Op opCode)   const;
   range_t  typeRange(spv::Op opCode)      const;
   range_t  constRange(spv::Op opCode)     const;
   unsigned typeSizeInWords(spv::Id id)    const;
   unsigned idTypeSizeInWords(spv::Id id)  const;
   
   spv::Id&        asId(unsigned word)                { return spv[word]; }
   const spv::Id&  asId(unsigned word)          const { return spv[word]; }
   spv::Op         asOpCode(unsigned word)      const { return opOpCode(spv[word]); }
   std::uint32_t   asOpCodeHash(unsigned word);
   spv::Decoration asDecoration(unsigned word)  const { return spv::Decoration(spv[word]); }
   unsigned        asWordCount(unsigned word)   const { return opWordCount(spv[word]); }
   spv::Id         asTypeConstId(unsigned word) const { return asId(word + (isTypeOp(asOpCode(word)) ? 1 : 2)); }
   unsigned        idPos(spv::Id id)            const;

   static unsigned opWordCount(spirword_t data) { return data >> spv::WordCountShift; }
   static spv::Op  opOpCode(spirword_t data)    { return spv::Op(data & spv::OpCodeMask); }

   // Header access & set methods
   spirword_t  magic()    const       { return spv[0]; } // return magic number
   spirword_t  bound()    const       { return spv[3]; } // return Id bound from header
   spirword_t  bound(spirword_t b)    { return spv[3] = b; };
   spirword_t  genmagic() const       { return spv[2]; } // generator magic
   spirword_t  genmagic(spirword_t m) { return spv[2] = m; }
   spirword_t  schemaNum() const      { return spv[4]; } // schema number from header

   // Mapping fns: get
   spv::Id     localId(spv::Id id) const { return idMapL[id]; }

   // Mapping fns: set
   inline spv::Id   localId(spv::Id id, spv::Id newId);
   void             countIds(spv::Id id);

   // Return next unused new local ID.
   // NOTE: boost::dynamic_bitset would be more efficient due to find_next(),
   // which std::vector<bool> doens't have.
   inline spv::Id   nextUnusedId(spv::Id id);

   void buildLocalMaps();
   std::string literalString(unsigned word) const; // Return literal as a std::string
   int literalStringWords(const std::string& str) const { return (int(str.size())+4)/4; }

   bool isNewIdMapped(spv::Id newId)   const { return isMapped(newId);            }
   bool isOldIdUnmapped(spv::Id oldId) const { return localId(oldId) == unmapped; }
   bool isOldIdUnused(spv::Id oldId)   const { return localId(oldId) == unused;   }
   bool isOldIdMapped(spv::Id oldId)   const { return !isOldIdUnused(oldId) && !isOldIdUnmapped(oldId); }
   bool isFunction(spv::Id oldId)      const { return fnPos.find(oldId) != fnPos.end(); }

   // bool    matchType(const globaltypes_t& globalTypes, spv::Id lt, spv::Id gt) const;
   // spv::Id findType(const globaltypes_t& globalTypes, spv::Id lt) const;
   std::uint32_t hashType(unsigned typeStart) const;

   spirvbin_t& process(instfn_t, idfn_t, unsigned begin = 0, unsigned end = 0);
   int         processInstruction(unsigned word, instfn_t, idfn_t);

   void        validate() const;
   void        mapTypeConst();
   void        mapFnBodies();
   void        optLoadStore();
   void        dceFuncs();
   void        dceVars();
   void        dceTypes();
   void        mapNames();
   void        foldIds();  // fold IDs to smallest space
   void        forwardLoadStores(); // load store forwarding (EXPERIMENTAL)
   void        offsetIds(); // create relative offset IDs

   void        applyMap();            // remap per local name map
   void        mapRemainder();        // map any IDs we haven't touched yet
   void        stripDebug();          // strip all debug info
   void        stripDeadRefs();       // strips debug info for now-dead references after DCE
   void        strip();               // remove debug symbols
   
   std::vector<spirword_t> spv;      // SPIR words

   namemap_t               nameMap;  // ID names from OpName

   // Since we want to also do binary ops, we can't use std::vector<bool>.  we could use
   // boost::dynamic_bitset, but we're trying to avoid a boost dependency.
   typedef std::uint64_t bits_t;
   std::vector<bits_t> mapped; // which new IDs have been mapped
   static const int mBits = sizeof(bits_t) * 4;

   bool isMapped(spv::Id id) const  { return id < maxMappedId() && ((mapped[id/mBits] & (1LL<<(id%mBits))) != 0); }
   void setMapped(spv::Id id) { resizeMapped(id); mapped[id/mBits] |= (1LL<<(id%mBits)); }
   void resizeMapped(spv::Id id) { if (id >= maxMappedId()) mapped.resize(id/mBits+1, 0); }
   size_t maxMappedId() const { return mapped.size() * mBits; }

   // Add a strip range for a given instruction starting at 'start'
   // Note: avoiding brace initializers to please older versions os MSVC.
   void stripInst(unsigned start) { stripRange.push_back(range_t(start, start + asWordCount(start))); }

   // Function start and end.  use unordered_map because we'll have
   // many fewer functions than IDs.
   std::unordered_map<spv::Id, range_t> fnPos;

   // Which functions are called, anywhere in the module, with a call count
   std::unordered_map<spv::Id, int> fnCalls;
   
   posmap_t       typeConstPos;  // word positions that define types & consts (ordered)
   posmap_rev_t   idPosR;        // reverse map from IDs to positions
   typesize_map_t idTypeSizeMap; // maps each ID to its type size, if known.
   
   std::vector<spv::Id>  idMapL;   // ID {M}ap from {L}ocal to {G}lobal IDs

   spv::Id entryPoint;      // module entry point
   spv::Id largestNewId;    // biggest new ID we have mapped anything to

   // Sections of the binary to strip, given as [begin,end)
   std::vector<range_t> stripRange;

   // processing options:
   std::uint32_t options;
   int           verbose;     // verbosity level

   static errorfn_t errorHandler;
   static logfn_t   logHandler;
};

} // namespace SPV

#endif // defined (use_cpp11)
#endif // SPIRVREMAPPER_H
