/* Common subexpression elimination for GNU compiler.
   Copyright (C) 1987-2015 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 GCC_CSELIB_H
#define GCC_CSELIB_H

/* Describe a value.  */
struct cselib_val {
  /* The hash value.  */
  unsigned int hash;

  /* A unique id assigned to values.  */
  int uid;

  /* A VALUE rtx that points back to this structure.  */
  rtx val_rtx;

  /* All rtl expressions that hold this value at the current time during a
     scan.  */
  struct elt_loc_list *locs;

  /* If this value is used as an address, points to a list of values that
     use it as an address in a MEM.  */
  struct elt_list *addr_list;

  struct cselib_val *next_containing_mem;
};

/* A list of rtl expressions that hold the same value.  */
struct elt_loc_list {
  /* Next element in the list.  */
  struct elt_loc_list *next;
  /* An rtl expression that holds the value.  */
  rtx loc;
  /* The insn that made the equivalence.  */
  rtx_insn *setting_insn;
};

/* Describe a single set that is part of an insn.  */
struct cselib_set
{
  rtx src;
  rtx dest;
  cselib_val *src_elt;
  cselib_val *dest_addr_elt;
};

enum cselib_record_what
{
  CSELIB_RECORD_MEMORY = 1,
  CSELIB_PRESERVE_CONSTANTS = 2
};

extern void (*cselib_discard_hook) (cselib_val *);
extern void (*cselib_record_sets_hook) (rtx_insn *insn, struct cselib_set *sets,
					int n_sets);

extern cselib_val *cselib_lookup (rtx, machine_mode,
				  int, machine_mode);
extern cselib_val *cselib_lookup_from_insn (rtx, machine_mode,
					    int, machine_mode, rtx_insn *);
extern void cselib_init (int);
extern void cselib_clear_table (void);
extern void cselib_finish (void);
extern void cselib_process_insn (rtx_insn *);
extern bool fp_setter_insn (rtx);
extern machine_mode cselib_reg_set_mode (const_rtx);
extern int rtx_equal_for_cselib_p (rtx, rtx);
extern int references_value_p (const_rtx, int);
extern rtx cselib_expand_value_rtx (rtx, bitmap, int);
typedef rtx (*cselib_expand_callback)(rtx, bitmap, int, void *);
extern rtx cselib_expand_value_rtx_cb (rtx, bitmap, int,
				       cselib_expand_callback, void *);
extern bool cselib_dummy_expand_value_rtx_cb (rtx, bitmap, int,
					      cselib_expand_callback, void *);
extern rtx cselib_subst_to_values (rtx, machine_mode);
extern rtx cselib_subst_to_values_from_insn (rtx, machine_mode, rtx_insn *);
extern void cselib_invalidate_rtx (rtx);

extern void cselib_reset_table (unsigned int);
extern unsigned int cselib_get_next_uid (void);
extern void cselib_preserve_value (cselib_val *);
extern bool cselib_preserved_value_p (cselib_val *);
extern void cselib_preserve_only_values (void);
extern void cselib_preserve_cfa_base_value (cselib_val *, unsigned int);
extern void cselib_add_permanent_equiv (cselib_val *, rtx, rtx_insn *);
extern bool cselib_have_permanent_equivalences (void);
extern void cselib_set_value_sp_based (cselib_val *);
extern bool cselib_sp_based_value_p (cselib_val *);

extern void dump_cselib_table (FILE *);

/* Return the canonical value for VAL, following the equivalence chain
   towards the earliest (== lowest uid) equivalent value.  */

static inline cselib_val *
canonical_cselib_val (cselib_val *val)
{
  cselib_val *canon;

  if (!val->locs || val->locs->next
      || !val->locs->loc || GET_CODE (val->locs->loc) != VALUE
      || val->uid < CSELIB_VAL_PTR (val->locs->loc)->uid)
    return val;

  canon = CSELIB_VAL_PTR (val->locs->loc);
  gcc_checking_assert (canonical_cselib_val (canon) == canon);
  return canon;
}

#endif /* GCC_CSELIB_H */
