// Instruction-related RTL SSA classes                              -*- C++ -*-
// Copyright (C) 2020-2021 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/>.

namespace rtl_ssa {

// A fake cost for instructions that we haven't costed yet.
const int UNKNOWN_COST = INT_MAX;

// Enumerates the kinds of note that can be added to an instruction.
// See the comment above insn_info for details.
enum class insn_note_kind : uint8_t
{
  ORDER_NODE,
  CALL_CLOBBERS
};

// The base class for notes that can be added to an instruction.
// See the comment above insn_info for details.
class insn_note
{
  // Size: 2 LP64 words.
  friend class insn_info;
  friend class function_info;

public:
  // Return what kind of note this is.
  insn_note_kind kind () const { return m_kind; }

  // Return the next note in the list, or null if none.
  insn_note *next_note () const { return m_next_note; }

  // Used with T = Derived *, where Derived is derived from insn_note.
  // Convert the note to Derived, asserting that it has the right kind.
  template<typename T>
  T as_a ();

  // Used with T = Derived *, where Derived is derived from insn_note.
  // If the note is a Derived note, return it in that form, otherwise
  // return null.
  template<typename T>
  T dyn_cast ();

protected:
  // Construct a note with the given kind.
  insn_note (insn_note_kind);

private:
  // The next note in the list, or null if none.
  insn_note *m_next_note;

  // The kind of note this is.
  insn_note_kind m_kind : 8;

protected:
  // Fill in the remaining LP64 word with data that derived classes can use.
  unsigned int m_data8 : 8;
  unsigned int m_data16 : 16;
  unsigned int m_data32 : 32;
};

// Instructions have one of these notes if insn_info::has_call_clobbers ()
// is true.  All such instructions in an EBB are first grouped together
// by the predefined_function_abis of the functions that they call.
// Then, for each such predefined ABI, the call_clobbers notes are put
// into a splay tree whose nodes follow execution order.
class insn_call_clobbers_note : public insn_note
{
  friend class function_info;
  friend class default_splay_tree_accessors<insn_call_clobbers_note *>;

public:
  static const insn_note_kind kind = insn_note_kind::CALL_CLOBBERS;

  // Return the identifier of the predefined_function_abi.
  unsigned int abi_id () const { return m_data32; }

  // Return the instruction to which the note is attached.
  insn_info *insn () const { return m_insn; }

protected:
  insn_call_clobbers_note (unsigned int abi_id, insn_info *insn);

  // The splay tree pointers.
  insn_call_clobbers_note *m_children[2];

  // The value returned by insn ().
  insn_info *m_insn;
};

// A splay tree of insn_call_clobbers_notes.
using insn_call_clobbers_tree = default_splay_tree<insn_call_clobbers_note *>;

// SSA-related information about an instruction.  It also represents
// artificial instructions that are added to make the dataflow correct;
// these artificial instructions fall into three categories:
//
// - Instructions that hold the phi nodes for an extended basic block (is_phi).
//
// - Instructions that represent the head of a basic block and that hold
//   all the associated artificial uses and definitions.
//
// - Instructions that represent the end of a basic block and that again
//   hold all the associated artificial uses and definitions.
//
// Dataflow-wise, each instruction goes through three stages:
//
// (1) Use all the values in uses ().
//
// (2) If has_call_clobbers (), clobber the registers indicated by
//     insn_callee_abi.
//
// (3) Define all the values in defs ().
//
// Having stage (2) is a trade-off: it makes processing the instructions
// more complicated, but it saves having to allocate memory for every
// individual call clobber.  Without it, clobbers for calls would often
// make up a large proportion of the total definitions in a function.
//
// All the instructions in a function are chained together in a list
// that follows a reverse postorder traversal of the CFG.  The list
// contains both debug and nondebug instructions, but it is possible
// to hop from one nondebug instruction to the next with constant complexity.
//
// Instructions can have supplemental information attached in the form
// of "notes", a bit like REG_NOTES for the underlying RTL insns.
class insn_info
{
  // Size: 8 LP64 words.
  friend class ebb_info;
  friend class function_info;

public:
  // Compare instructions by their positions in the function list described
  // above.  Thus for two instructions in the same basic block, I1 < I2 if
  // I1 comes before I2 in the block.
  bool operator< (const insn_info &) const;
  bool operator<= (const insn_info &) const;
  bool operator>= (const insn_info &) const;
  bool operator> (const insn_info &) const;

  // Return -1 if this instruction comes before INSN in the reverse
  // postorder, 0 if this instruction is INSN, or 1 if this instruction
  // comes after INSN in the reverse postorder.
  int compare_with (const insn_info *insn) const;

  // Return the previous and next instructions in the list described above,
  // or null if there are no such instructions.
  insn_info *prev_any_insn () const;
  insn_info *next_any_insn () const;

  // Only valid if !is_debug_insn ().  Return the previous and next
  // nondebug instructions in the list described above, skipping over
  // any intervening debug instructions.  These are constant-time operations.
  insn_info *prev_nondebug_insn () const;
  insn_info *next_nondebug_insn () const;

  // Return the underlying RTL insn.  This instruction is null if is_phi ()
  // or is_bb_end () are true.  The instruction is a basic block note if
  // is_bb_head () is true.
  rtx_insn *rtl () const { return m_rtl; }

  // Return true if the instruction is a real insn with an rtl pattern.
  // Return false if it is an artificial instruction that represents the
  // phi nodes in an extended basic block or the head or end of a basic block.
  bool is_real () const { return m_cost_or_uid >= 0; }

  // Return the opposite of is_real ().
  bool is_artificial () const { return m_cost_or_uid < 0; }

  // Return true if the instruction was a real instruction but has now
  // been deleted.  In this case the instruction is no longer part of
  // the SSA information.
  bool has_been_deleted () const { return m_rtl && !INSN_P (m_rtl); }

  // Return true if the instruction is a debug instruction (and thus
  // also a real instruction).
  bool is_debug_insn () const { return m_is_debug_insn; }

  // Return true if the instruction is something that we can optimize.
  // This implies that it is a real instruction that contains an asm
  // or that contains something that matches an .md define_insn pattern.
  bool can_be_optimized () const { return m_can_be_optimized; }

  // Return true if the instruction is a call instruction.
  //
  // ??? We could cache this information, but since most callers would
  // go on to access PATTERN (rtl ()), a cache might not be helpful and
  // could even be counterproductive.
  bool is_call () const { return CALL_P (m_rtl); }

  // Return true if the instruction is a jump instruction.
  //
  // ??? See is_call for the reason we don't cache this.
  bool is_jump () const { return JUMP_P (m_rtl); }

  // Return true if the instruction is real and contains an inline asm.
  bool is_asm () const { return m_is_asm; }

  // Return true if the instruction is real and includes an RTX_AUTOINC
  // operation.
  bool has_pre_post_modify () const { return m_has_pre_post_modify; }

  // Return true if the instruction is real and has volatile references,
  // in the sense of volatile_refs_p.  This includes volatile memory,
  // volatile asms and UNSPEC_VOLATILEs.
  bool has_volatile_refs () const { return m_has_volatile_refs; }

  // Return true if the instruction is aritificial and if its (sole)
  // purpose is to hold the phi nodes in an extended basic block.
  bool is_phi () const;

  // Return true if the instruction is artificial and if it represents
  // the head of a basic block.  If so, the instruction conceptually
  // executes before the real instructions in the block.  The uses
  // and definitions represent the df_get_artificial_uses and
  // df_get_artificial_defs entries for the head of the block.
  bool is_bb_head () const;

  // Return true if the instruction is artificial and if it represents
  // the end of a basic block.  The uses and definitions represent the
  // the df_get_artificial_uses and df_get_artificial_defs entries for
  // the end of the block.
  bool is_bb_end () const;

  // Return the basic block that the instruction is in.
  bb_info *bb () const { return m_bb; }

  // Return the extended basic block that the instruction is in;
  // see bb_info for details.
  ebb_info *ebb () const;

  // If the instruction is real, return the unique identifier of the
  // underlying RTL insn.  If the instruction is artificial, return
  // a unique negative identifier for the instructions.
  //
  // Note that the identifiers are not linear: it can be the case that
  // an instruction with a higher uid comes earlier in a block than an
  // instruction with a lower uid.  The identifiers are however persistent;
  // the identifier remains the same after the instruction has been moved
  // or changed.
  int uid () const;

  // Return the list of things that this instruction uses.  Registers
  // come first, in register number order, followed by memory.
  use_array uses () const;

  // Return true if the instruction is a call and if the clobbers
  // described by insn_callee_abi have been omitted from the list
  // of definitions.
  bool has_call_clobbers () const;

  // Return the list of things that this instruction sets or clobbers.
  // Registers come first, in register number order, followed by memory.
  //
  // If has_call_clobbers () is true, the list omits both the full and
  // partial register clobbers described by insn_callee_abi.
  def_array defs () const;

  // The number of entries in uses ().
  unsigned int num_uses () const { return m_num_uses; }

  // The number of entries in defs ().
  unsigned int num_defs () const { return m_num_defs; }

  // Return the cost of the instruction, as calculated by the target.
  // For performance reasons, the cost is evaluated lazily on first use.
  //
  // Artificial instructions have a cost of 0.
  unsigned int cost () const;

  // Return the first insn_note attached to the instruction, or null
  // if none.
  insn_note *first_note () const { return m_first_note; }

  // See if a note of type T is attached to the instruction.  Return it
  // if so, otherwise return null.
  template<typename T>
  const T *find_note () const;

  // Print "i" + uid () for real instructions and "a" + -uid () for
  // artificial instructions.
  void print_identifier (pretty_printer *) const;

  // Print a short(ish) description of where the instruction is.
  void print_location (pretty_printer *) const;

  // Combine print_identifier and print_location.
  void print_identifier_and_location (pretty_printer *) const;

  // Print a full description of the instruction.
  void print_full (pretty_printer *) const;

private:
  // The first-order way of representing the order between instructions
  // is to assign "program points", with higher point numbers coming
  // later in the reverse postorder than lower point numbers.  However,
  // after a sequence of instruction movements, we may end up in a situation
  // that adjacent instructions have the same program point.
  //
  // When that happens, we put the instructions into a splay tree that
  // records their relative order.  Each node of the splay tree is an
  // order_node note that is attached to its respective instruction.
  // The root of the splay tree is not stored, since the only thing
  // we need the tree for is to compare two nodes.
  class order_node : public insn_note
  {
  public:
    static const insn_note_kind kind = insn_note_kind::ORDER_NODE;

    order_node (int uid);

    // Return the uid of the instruction that this node describes.
    int uid () const { return m_data32; }

    // The splay tree pointers.
    order_node *m_children[2];
    order_node *m_parent;
  };
  using order_splay_tree = default_rootless_splay_tree<order_node *>;

  // prev_insn_or_last_debug_insn represents a choice between two things:
  //
  // (1) A pointer to the previous instruction in the list that has the
  //     same is_debug_insn () value, or null if no such instruction exists.
  //
  // (2) A pointer to the end of a sublist of debug instructions.
  //
  // (2) is used if this instruction is a debug instruction and the
  // previous instruction is not.  (1) is used otherwise.
  //
  // next_nondebug_or_debug_insn points to the next instruction but also
  // records whether that next instruction is a debug instruction or a
  // nondebug instruction.
  //
  // Thus the list is chained as follows:
  //
  //         ---->        ---->     ---->     ---->     ---->
  // NONDEBUG     NONDEBUG     DEBUG     DEBUG     DEBUG     NONDEBUG ...
  //         <----    ^     +--     <----     <----  ^    +--
  //                  |     |                        |    |
  //                  |     +------------------------+    |
  //                  |                                   |
  //                  +-----------------------------------+
  using prev_insn_or_last_debug_insn = pointer_mux<insn_info>;
  using next_nondebug_or_debug_insn = pointer_mux<insn_info>;

  insn_info (bb_info *bb, rtx_insn *rtl, int cost_or_uid);

  static void print_uid (pretty_printer *, int);

  void calculate_cost () const;
  void set_properties (const rtx_properties &);
  void set_accesses (access_info **, unsigned int, unsigned int);
  void copy_accesses (access_array, access_array);
  void set_cost (unsigned int cost) { m_cost_or_uid = cost; }
  void set_bb (bb_info *bb) { m_bb = bb; }

  void add_note (insn_note *note);

  order_node *get_order_node () const;
  order_node *get_known_order_node () const;
  int slow_compare_with (const insn_info &) const;

  insn_info *last_debug_insn () const;

  unsigned int point () const { return m_point; }
  void copy_prev_from (insn_info *);
  void copy_next_from (insn_info *);
  void set_prev_sametype_insn (insn_info *);
  void set_last_debug_insn (insn_info *);
  void set_next_any_insn (insn_info *);
  void set_point (unsigned int point) { m_point = point; }
  void clear_insn_links ();
  bool has_insn_links ();

  // The values returned by the accessors above.
  prev_insn_or_last_debug_insn m_prev_insn_or_last_debug_insn;
  next_nondebug_or_debug_insn m_next_nondebug_or_debug_insn;
  bb_info *m_bb;
  rtx_insn *m_rtl;

  // The list of definitions followed by the list of uses.
  access_info **m_accesses;

  // The number of definitions and the number uses.  FIRST_PSEUDO_REGISTER + 1
  // is the maximum number of accesses to hard registers and memory, and
  // MAX_RECOG_OPERANDS is the maximum number of pseudos that can be
  // defined by an instruction, so the number of definitions should fit
  // easily in 16 bits.
  unsigned int m_num_uses;
  unsigned int m_num_defs : 16;

  // Flags returned by the accessors above.
  unsigned int m_is_debug_insn : 1;
  unsigned int m_can_be_optimized : 1;
  unsigned int m_is_asm : 1;
  unsigned int m_has_pre_post_modify : 1;
  unsigned int m_has_volatile_refs : 1;

  // For future expansion.
  unsigned int m_spare : 11;

  // The program point at which the instruction occurs.
  //
  // Note that the values of the program points are influenced by -g
  // and so should not used to make codegen decisions.
  unsigned int m_point;

  // Negative if the instruction is artificial, nonnegative if it is real.
  //
  // For real instructions: the cost of the instruction, or UNKNOWN_COST
  // if we haven't measured it yet.
  //
  // For artificial instructions: the (negative) unique identifier of the
  // instruction.
  mutable int m_cost_or_uid;

  // The list of notes that have been attached to the instruction.
  insn_note *m_first_note;
};

// Iterators for unfiltered lists of instructions.
using any_insn_iterator = list_iterator<insn_info, &insn_info::next_any_insn>;
using reverse_any_insn_iterator
  = list_iterator<insn_info, &insn_info::prev_any_insn>;

// Iterators for nondebug instructions only.
using nondebug_insn_iterator
  = list_iterator<insn_info, &insn_info::next_nondebug_insn>;
using reverse_nondebug_insn_iterator
  = list_iterator<insn_info, &insn_info::prev_nondebug_insn>;

// A class that describes an inclusive range of instructions.
class insn_range_info
{
public:
  insn_range_info () = default;

  // Create a range that contains a singleton instruction.
  insn_range_info (insn_info *insn) : first (insn), last (insn) {}

  // Create a range [FIRST, LAST], given that *FIRST <= *LAST.
  insn_range_info (insn_info *first, insn_info *last);

  // Return true if the range contains at least one instruction.
  explicit operator bool () const { return *first <= *last; }

  bool operator== (const insn_range_info &) const;
  bool operator!= (const insn_range_info &) const;

  // If the range contains a single instruction, return that instruction,
  // otherwise return null.
  insn_info *singleton () const;

  // Return true if the range includes INSN.
  bool includes (insn_info *insn) const;

  // If INSN is inside the range, return INSN, otherwise return the
  // nearest in-range instruction.
  insn_info *clamp_insn_to_range (insn_info *insn) const;

  // Return true if this range is a subrange of OTHER, i.e. if OTHER
  // includes every instruction that this range does.
  bool is_subrange_of (const insn_range_info &other) const;

  // The lower and upper bounds of the range.
  insn_info *first;
  insn_info *last;
};

// A class that represents a closure of operator== for instructions.
// This is used by insn_is; see there for details.
class insn_is_closure
{
public:
  insn_is_closure (const insn_info *insn) : m_insn (insn) {}
  bool operator() (const insn_info *other) const { return m_insn == other; }

private:
  const insn_info *m_insn;
};

void pp_insn (pretty_printer *, const insn_info *);

}

void dump (FILE *, const rtl_ssa::insn_info *);

void DEBUG_FUNCTION debug (const rtl_ssa::insn_info *);
