/* An incremental hash abstract data type.
   Copyright (C) 2014-2022 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#ifndef INCHASH_H
#define INCHASH_H 1


/* This file implements an incremential hash function ADT, to be used
   by code that incrementially hashes a lot of unrelated data
   (not in a single memory block) into a single value. The goal
   is to make it easy to plug in efficient hash algorithms.
   Currently it just implements the plain old jhash based
   incremental hash from gcc's tree.cc.  */

hashval_t iterative_hash_host_wide_int (HOST_WIDE_INT, hashval_t);
hashval_t iterative_hash_hashval_t (hashval_t, hashval_t);

namespace inchash
{

class hash
{
 public:

  /* Start incremential hashing, optionally with SEED.  */
  hash (hashval_t seed = 0)
  {
    val = seed;
    bits = 0;
  }

  /* End incremential hashing and provide the final value.  */
  hashval_t end ()
  {
    return val;
  }

  /* Add unsigned value V.  */
  void add_int (unsigned v)
  {
    val = iterative_hash_hashval_t (v, val);
  }

  /* Add polynomial value V, treating each element as an unsigned int.  */
  template<unsigned int N, typename T>
  void add_poly_int (const poly_int_pod<N, T> &v)
  {
    for (unsigned int i = 0; i < N; ++i)
      add_int (v.coeffs[i]);
  }

  /* Add HOST_WIDE_INT value V.  */
  void add_hwi (HOST_WIDE_INT v)
  {
    val = iterative_hash_host_wide_int (v, val);
  }

  /* Add polynomial value V, treating each element as a HOST_WIDE_INT.  */
  template<unsigned int N, typename T>
  void add_poly_hwi (const poly_int_pod<N, T> &v)
  {
    for (unsigned int i = 0; i < N; ++i)
      add_hwi (v.coeffs[i]);
  }

  /* Add wide_int-based value V.  */
  template<typename T>
  void add_wide_int (const generic_wide_int<T> &x)
  {
    add_int (x.get_len ());
    for (unsigned i = 0; i < x.get_len (); i++)
      add_hwi (x.sext_elt (i));
  }

  /* Hash in pointer PTR.  */
  void add_ptr (const void *ptr)
  {
    add (&ptr, sizeof (ptr));
  }

  /* Add a memory block DATA with size LEN.  */
  void add (const void *data, size_t len)
  {
    val = iterative_hash (data, len, val);
  }

  /* Merge hash value OTHER.  */
  void merge_hash (hashval_t other)
  {
    val = iterative_hash_hashval_t (other, val);
  }

  /* Hash in state from other inchash OTHER.  */
  void merge (hash &other)
  {
    merge_hash (other.val);
  }

  template<class T> void add_object(T &obj)
  {
    add (&obj, sizeof(T));
  }

  /* Support for accumulating boolean flags */

  void add_flag (bool flag)
  {
    bits = (bits << 1) | flag;
  }

  void commit_flag ()
  {
    add_int (bits);
    bits = 0;
  }

  /* Support for commutative hashing. Add A and B in a defined order
     based on their value. This is useful for hashing commutative
     expressions, so that A+B and B+A get the same hash.  */

  void add_commutative (hash &a, hash &b)
  {
    if (a.end() > b.end())
      {
	merge (b);
	merge (a);
      }
    else
      {
	merge (a);
	merge (b);
      }
  }

 private:
  hashval_t val;
  unsigned bits;
};

}

/* Borrowed from hashtab.c iterative_hash implementation.  */
#define mix(a,b,c) \
{ \
  a -= b; a -= c; a ^= (c>>13); \
  b -= c; b -= a; b ^= (a<< 8); \
  c -= a; c -= b; c ^= ((b&0xffffffff)>>13); \
  a -= b; a -= c; a ^= ((c&0xffffffff)>>12); \
  b -= c; b -= a; b = (b ^ (a<<16)) & 0xffffffff; \
  c -= a; c -= b; c = (c ^ (b>> 5)) & 0xffffffff; \
  a -= b; a -= c; a = (a ^ (c>> 3)) & 0xffffffff; \
  b -= c; b -= a; b = (b ^ (a<<10)) & 0xffffffff; \
  c -= a; c -= b; c = (c ^ (b>>15)) & 0xffffffff; \
}


/* Produce good hash value combining VAL and VAL2.  */
inline
hashval_t
iterative_hash_hashval_t (hashval_t val, hashval_t val2)
{
  /* the golden ratio; an arbitrary value.  */
  hashval_t a = 0x9e3779b9;

  mix (a, val, val2);
  return val2;
}

/* Produce good hash value combining VAL and VAL2.  */

inline
hashval_t
iterative_hash_host_wide_int (HOST_WIDE_INT val, hashval_t val2)
{
  if (sizeof (HOST_WIDE_INT) == sizeof (hashval_t))
    return iterative_hash_hashval_t (val, val2);
  else
    {
      hashval_t a = (hashval_t) val;
      /* Avoid warnings about shifting of more than the width of the type on
         hosts that won't execute this path.  */
      int zero = 0;
      hashval_t b = (hashval_t) (val >> (sizeof (hashval_t) * 8 + zero));
      mix (a, b, val2);
      if (sizeof (HOST_WIDE_INT) > 2 * sizeof (hashval_t))
	{
	  hashval_t a = (hashval_t) (val >> (sizeof (hashval_t) * 16 + zero));
	  hashval_t b = (hashval_t) (val >> (sizeof (hashval_t) * 24 + zero));
	  mix (a, b, val2);
	}
      return val2;
    }
}

#endif
