//
// 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>
#include <exception>

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 || (defined(_MSC_VER) && _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), errorLatch(false)
   { }

   virtual ~spirvbin_t() { }

   // 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 { errorLatch = true; 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

   // Error latch: this is set if the error handler is ever executed.  It would be better to
   // use a try/catch block and throw, but that's not desired for certain environments, so
   // this is the alternative.
   mutable bool errorLatch;

   static errorfn_t errorHandler;
   static logfn_t   logHandler;
};

} // namespace SPV

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