/* read-rtl-function.c - Reader for RTL function dumps
   Copyright (C) 2016-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/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "tree.h"
#include "diagnostic.h"
#include "read-md.h"
#include "rtl.h"
#include "cfghooks.h"
#include "stringpool.h"
#include "function.h"
#include "tree-cfg.h"
#include "cfg.h"
#include "basic-block.h"
#include "cfgrtl.h"
#include "memmodel.h"
#include "emit-rtl.h"
#include "cgraph.h"
#include "tree-pass.h"
#include "toplev.h"
#include "varasm.h"
#include "read-rtl-function.h"
#include "selftest.h"
#include "selftest-rtl.h"
#include "regs.h"
#include "function-abi.h"

/* Forward decls.  */
class function_reader;
class fixup;

/* Edges are recorded when parsing the "insn-chain" directive,
   and created at the end when all the blocks ought to exist.
   This struct records an "edge-from" or "edge-to" directive seen
   at LOC, which will be turned into an actual CFG edge once
   the "insn-chain" is fully parsed.  */

class deferred_edge
{
public:
  deferred_edge (file_location loc, int src_bb_idx, int dest_bb_idx, int flags)
  : m_loc (loc), m_src_bb_idx (src_bb_idx), m_dest_bb_idx (dest_bb_idx),
    m_flags (flags)
  {}

  file_location m_loc;
  int m_src_bb_idx;
  int m_dest_bb_idx;
  int m_flags;
};

/* Subclass of rtx_reader for reading function dumps.  */

class function_reader : public rtx_reader
{
 public:
  function_reader ();
  ~function_reader ();

  /* Overridden vfuncs of class md_reader.  */
  void handle_unknown_directive (file_location, const char *) FINAL OVERRIDE;

  /* Overridden vfuncs of class rtx_reader.  */
  rtx read_rtx_operand (rtx x, int idx) FINAL OVERRIDE;
  void handle_any_trailing_information (rtx x) FINAL OVERRIDE;
  rtx postprocess (rtx) FINAL OVERRIDE;
  const char *finalize_string (char *stringbuf) FINAL OVERRIDE;

  rtx_insn **get_insn_by_uid (int uid);
  tree parse_mem_expr (const char *desc);

 private:
  void parse_function ();
  void create_function ();
  void parse_param ();
  void parse_insn_chain ();
  void parse_block ();
  int parse_bb_idx ();
  void parse_edge (basic_block block, bool from);
  rtx_insn *parse_insn (file_location loc, const char *name);
  void parse_cfg (file_location loc);
  void parse_crtl (file_location loc);
  void create_edges ();

  int parse_enum_value (int num_values, const char *const *strings);

  void read_rtx_operand_u (rtx x, int idx);
  void read_rtx_operand_i_or_n (rtx x, int idx, char format_char);
  rtx read_rtx_operand_r (rtx x);
  rtx extra_parsing_for_operand_code_0 (rtx x, int idx);

  void add_fixup_insn_uid (file_location loc, rtx insn, int operand_idx,
			   int insn_uid);

  void add_fixup_note_insn_basic_block (file_location loc, rtx insn,
					int operand_idx, int bb_idx);

  void add_fixup_source_location (file_location loc, rtx_insn *insn,
				  const char *filename, int lineno, int colno);

  void add_fixup_expr (file_location loc, rtx x,
		       const char *desc);

  rtx consolidate_singletons (rtx x);
  rtx parse_rtx ();
  void maybe_read_location (rtx_insn *insn);

  void handle_insn_uids ();
  void apply_fixups ();

 private:
  struct uid_hash : int_hash <int, -1, -2> {};
  hash_map<uid_hash, rtx_insn *> m_insns_by_uid;
  auto_vec<fixup *> m_fixups;
  rtx_insn *m_first_insn;
  auto_vec<tree> m_fake_scope;
  char *m_name;
  bool m_have_crtl_directive;
  basic_block m_bb_to_insert_after;
  auto_vec <deferred_edge> m_deferred_edges;
  int m_highest_bb_idx;
};

/* Abstract base class for recording post-processing steps that must be
   done after reading a .rtl file.  */

class fixup
{
 public:
  /* Constructor for a fixup at LOC affecting X.  */
  fixup (file_location loc, rtx x)
    : m_loc (loc), m_rtx (x)
  {}
  virtual ~fixup () {}

  virtual void apply (function_reader *reader) const = 0;

 protected:
  file_location m_loc;
  rtx m_rtx;
};

/* An abstract subclass of fixup for post-processing steps that
   act on a specific operand of a specific instruction.  */

class operand_fixup : public fixup
{
 public:
  /* Constructor for a fixup at LOC affecting INSN's operand
     with index OPERAND_IDX.  */
  operand_fixup (file_location loc, rtx insn, int operand_idx)
    : fixup (loc, insn), m_operand_idx (operand_idx)
  {}

 protected:
  int m_operand_idx;
};

/* A concrete subclass of operand_fixup: fixup an rtx_insn *
   field based on an integer UID.  */

class fixup_insn_uid : public operand_fixup
{
 public:
  /* Constructor for a fixup at LOC affecting INSN's operand
     with index OPERAND_IDX.  Record INSN_UID as the uid.  */
  fixup_insn_uid (file_location loc, rtx insn, int operand_idx, int insn_uid)
    : operand_fixup (loc, insn, operand_idx),
      m_insn_uid (insn_uid)
  {}

  void apply (function_reader *reader) const;

 private:
  int m_insn_uid;
};

/* A concrete subclass of operand_fixup: fix up a
   NOTE_INSN_BASIC_BLOCK based on an integer block ID.  */

class fixup_note_insn_basic_block : public operand_fixup
{
 public:
  fixup_note_insn_basic_block (file_location loc, rtx insn, int operand_idx,
			       int bb_idx)
    : operand_fixup (loc, insn, operand_idx),
      m_bb_idx (bb_idx)
  {}

  void apply (function_reader *reader) const;

 private:
  int m_bb_idx;
};

/* A concrete subclass of fixup (not operand_fixup): fix up
   the expr of an rtx (REG or MEM) based on a textual dump.  */

class fixup_expr : public fixup
{
 public:
  fixup_expr (file_location loc, rtx x, const char *desc)
    : fixup (loc, x),
      m_desc (xstrdup (desc))
  {}

  ~fixup_expr () { free (m_desc); }

  void apply (function_reader *reader) const;

 private:
  char *m_desc;
};

/* Return a textual description of the operand of INSN with
   index OPERAND_IDX.  */

static const char *
get_operand_name (rtx insn, int operand_idx)
{
  gcc_assert (is_a <rtx_insn *> (insn));
  switch (operand_idx)
    {
    case 0:
      return "PREV_INSN";
    case 1:
      return "NEXT_INSN";
    default:
      return NULL;
    }
}

/* Fixup an rtx_insn * field based on an integer UID, as read by READER.  */

void
fixup_insn_uid::apply (function_reader *reader) const
{
  rtx_insn **insn_from_uid = reader->get_insn_by_uid (m_insn_uid);
  if (insn_from_uid)
    XEXP (m_rtx, m_operand_idx) = *insn_from_uid;
  else
    {
      const char *op_name = get_operand_name (m_rtx, m_operand_idx);
      if (op_name)
	error_at (m_loc,
		  "insn with UID %i not found for operand %i (`%s') of insn %i",
		  m_insn_uid, m_operand_idx, op_name, INSN_UID (m_rtx));
      else
	error_at (m_loc,
		  "insn with UID %i not found for operand %i of insn %i",
		  m_insn_uid, m_operand_idx, INSN_UID (m_rtx));
    }
}

/* Fix up a NOTE_INSN_BASIC_BLOCK based on an integer block ID.  */

void
fixup_note_insn_basic_block::apply (function_reader *) const
{
  basic_block bb = BASIC_BLOCK_FOR_FN (cfun, m_bb_idx);
  gcc_assert (bb);
  NOTE_BASIC_BLOCK (m_rtx) = bb;
}

/* Fix up the expr of an rtx (REG or MEM) based on a textual dump
   read by READER.  */

void
fixup_expr::apply (function_reader *reader) const
{
  tree expr = reader->parse_mem_expr (m_desc);
  switch (GET_CODE (m_rtx))
    {
    case REG:
      set_reg_attrs_for_decl_rtl (expr, m_rtx);
      break;
    case MEM:
      set_mem_expr (m_rtx, expr);
      break;
    default:
      gcc_unreachable ();
    }
}

/* Strip trailing whitespace from DESC.  */

static void
strip_trailing_whitespace (char *desc)
{
  char *terminator = desc + strlen (desc);
  while (desc < terminator)
    {
      terminator--;
      if (ISSPACE (*terminator))
	*terminator = '\0';
      else
	break;
    }
}

/* Return the numeric value n for GET_NOTE_INSN_NAME (n) for STRING,
   or fail if STRING isn't recognized.  */

static int
parse_note_insn_name (const char *string)
{
  for (int i = 0; i < NOTE_INSN_MAX; i++)
    if (strcmp (string, GET_NOTE_INSN_NAME (i)) == 0)
      return i;
  fatal_with_file_and_line ("unrecognized NOTE_INSN name: `%s'", string);
}

/* Return the register number for NAME, or return -1 if it isn't
   recognized.  */

static int
lookup_reg_by_dump_name (const char *name)
{
  for (int i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    if (reg_names[i][0]
	&& ! strcmp (name, reg_names[i]))
      return i;

  /* Also lookup virtuals.  */
  if (!strcmp (name, "virtual-incoming-args"))
    return VIRTUAL_INCOMING_ARGS_REGNUM;
  if (!strcmp (name, "virtual-stack-vars"))
    return VIRTUAL_STACK_VARS_REGNUM;
  if (!strcmp (name, "virtual-stack-dynamic"))
    return VIRTUAL_STACK_DYNAMIC_REGNUM;
  if (!strcmp (name, "virtual-outgoing-args"))
    return VIRTUAL_OUTGOING_ARGS_REGNUM;
  if (!strcmp (name, "virtual-cfa"))
    return VIRTUAL_CFA_REGNUM;
  if (!strcmp (name, "virtual-preferred-stack-boundary"))
    return VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM;
  /* TODO: handle "virtual-reg-%d".  */

  /* In compact mode, pseudos are printed with '< and '>' wrapping the regno,
     offseting it by (LAST_VIRTUAL_REGISTER + 1), so that the
     first non-virtual pseudo is dumped as "<0>".  */
  if (name[0] == '<' && name[strlen (name) - 1] == '>')
    {
      int dump_num = atoi (name + 1);
      return dump_num + LAST_VIRTUAL_REGISTER + 1;
    }

  /* Not found.  */
  return -1;
}

/* class function_reader : public rtx_reader */

/* function_reader's constructor.  */

function_reader::function_reader ()
: rtx_reader (true),
  m_first_insn (NULL),
  m_name (NULL),
  m_have_crtl_directive (false),
  m_bb_to_insert_after (NULL),
  m_highest_bb_idx (EXIT_BLOCK)
{
}

/* function_reader's destructor.  */

function_reader::~function_reader ()
{
  int i;
  fixup *f;
  FOR_EACH_VEC_ELT (m_fixups, i, f)
    delete f;

  free (m_name);
}

/* Implementation of rtx_reader::handle_unknown_directive,
   for parsing the remainder of a directive with name NAME
   seen at START_LOC.

   Require a top-level "function" directive, as emitted by
   print_rtx_function, and parse it.  */

void
function_reader::handle_unknown_directive (file_location start_loc,
					   const char *name)
{
  if (strcmp (name, "function"))
    fatal_at (start_loc, "expected 'function'");

  if (flag_lto)
    error ("%<__RTL%> function cannot be compiled with %<-flto%>");

  parse_function ();
}

/* Parse the output of print_rtx_function (or hand-written data in the
   same format), having already parsed the "(function" heading, and
   finishing immediately before the final ")".

   The "param" and "crtl" clauses are optional.  */

void
function_reader::parse_function ()
{
  m_name = xstrdup (read_string (0));

  create_function ();

  while (1)
    {
      int c = read_skip_spaces ();
      if (c == ')')
	{
	  unread_char (c);
	  break;
	}
      unread_char (c);
      require_char ('(');
      file_location loc = get_current_location ();
      struct md_name directive;
      read_name (&directive);
      if (strcmp (directive.string, "param") == 0)
	parse_param ();
      else if (strcmp (directive.string, "insn-chain") == 0)
	parse_insn_chain ();
      else if (strcmp (directive.string, "crtl") == 0)
	parse_crtl (loc);
      else
	fatal_with_file_and_line ("unrecognized directive: %s",
				  directive.string);
    }

  handle_insn_uids ();

  apply_fixups ();

  /* Rebuild the JUMP_LABEL field of any JUMP_INSNs in the chain, and the
     LABEL_NUSES of any CODE_LABELs.

     This has to happen after apply_fixups, since only after then do
     LABEL_REFs have their label_ref_label set up.  */
  rebuild_jump_labels (get_insns ());

  crtl->init_stack_alignment ();
}

/* Set up state for the function *before* fixups are applied.

   Create "cfun" and a decl for the function.
   By default, every function decl is hardcoded as
      int test_1 (int i, int j, int k);
   Set up various other state:
   - the cfg and basic blocks (edges are created later, *after* fixups
   are applied).
   - add the function to the callgraph.  */

void
function_reader::create_function ()
{
  /* We start in cfgrtl mode, rather than cfglayout mode.  */
  rtl_register_cfg_hooks ();

  /* When run from selftests or "rtl1", cfun is NULL.
     When run from "cc1" for a C function tagged with __RTL, cfun is the
     tagged function.  */
  if (!cfun)
    {
      tree fn_name = get_identifier (m_name ? m_name : "test_1");
      tree int_type = integer_type_node;
      tree return_type = int_type;
      tree arg_types[3] = {int_type, int_type, int_type};
      tree fn_type = build_function_type_array (return_type, 3, arg_types);
      tree fndecl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, fn_name, fn_type);
      tree resdecl = build_decl (UNKNOWN_LOCATION, RESULT_DECL, NULL_TREE,
				 return_type);
      DECL_ARTIFICIAL (resdecl) = 1;
      DECL_IGNORED_P (resdecl) = 1;
      DECL_RESULT (fndecl) = resdecl;
      allocate_struct_function (fndecl, false);
      /* This sets cfun.  */
      current_function_decl = fndecl;
    }

  gcc_assert (cfun);
  gcc_assert (current_function_decl);
  tree fndecl = current_function_decl;

  /* Mark this function as being specified as __RTL.  */
  cfun->curr_properties |= PROP_rtl;

  /* cc1 normally inits DECL_INITIAL (fndecl) to be error_mark_node.
     Create a dummy block for it.  */
  DECL_INITIAL (fndecl) = make_node (BLOCK);

  cfun->curr_properties = (PROP_cfg | PROP_rtl);

  /* Do we need this to force cgraphunit.c to output the function? */
  DECL_EXTERNAL (fndecl) = 0;
  DECL_PRESERVE_P (fndecl) = 1;

  /* Add to cgraph.  */
  cgraph_node::finalize_function (fndecl, false);

  /* Create bare-bones cfg.  This creates the entry and exit blocks.  */
  init_empty_tree_cfg_for_function (cfun);
  ENTRY_BLOCK_PTR_FOR_FN (cfun)->flags |= BB_RTL;
  EXIT_BLOCK_PTR_FOR_FN (cfun)->flags |= BB_RTL;
  init_rtl_bb_info (ENTRY_BLOCK_PTR_FOR_FN (cfun));
  init_rtl_bb_info (EXIT_BLOCK_PTR_FOR_FN (cfun));
  m_bb_to_insert_after = ENTRY_BLOCK_PTR_FOR_FN (cfun);

}

/* Look within the params of FNDECL for a param named NAME.
   Return NULL_TREE if one isn't found.  */

static tree
find_param_by_name (tree fndecl, const char *name)
{
  for (tree arg = DECL_ARGUMENTS (fndecl); arg; arg = TREE_CHAIN (arg))
    if (id_equal (DECL_NAME (arg), name))
      return arg;
  return NULL_TREE;
}

/* Parse the content of a "param" directive, having already parsed the
   "(param".  Consume the trailing ')'.  */

void
function_reader::parse_param ()
{
  require_char_ws ('"');
  file_location loc = get_current_location ();
  char *name = read_quoted_string ();

  /* Lookup param by name.  */
  tree t_param = find_param_by_name (cfun->decl, name);
  if (!t_param)
    fatal_at (loc, "param not found: %s", name);

  /* Parse DECL_RTL.  */
  require_char_ws ('(');
  require_word_ws ("DECL_RTL");
  DECL_WRTL_CHECK (t_param)->decl_with_rtl.rtl = parse_rtx ();
  require_char_ws (')');

  /* Parse DECL_RTL_INCOMING.  */
  require_char_ws ('(');
  require_word_ws ("DECL_RTL_INCOMING");
  DECL_INCOMING_RTL (t_param) = parse_rtx ();
  require_char_ws (')');

  require_char_ws (')');
}

/* Parse zero or more child insn elements within an
   "insn-chain" element.  Consume the trailing ')'.  */

void
function_reader::parse_insn_chain ()
{
  while (1)
    {
      int c = read_skip_spaces ();
      file_location loc = get_current_location ();
      if (c == ')')
	break;
      else if (c == '(')
	{
	  struct md_name directive;
	  read_name (&directive);
	  if (strcmp (directive.string, "block") == 0)
	    parse_block ();
	  else
	    parse_insn (loc, directive.string);
	}
      else
	fatal_at (loc, "expected '(' or ')'");
    }

  create_edges ();
}

/* Parse zero or more child directives (edges and insns) within a
   "block" directive, having already parsed the "(block " heading.
   Consume the trailing ')'.  */

void
function_reader::parse_block ()
{
  /* Parse the index value from the dump.  This will be an integer;
     we don't support "entry" or "exit" here (unlike for edges).  */
  struct md_name name;
  read_name (&name);
  int bb_idx = atoi (name.string);

  /* The term "index" has two meanings for basic blocks in a CFG:
     (a) the "index" field within struct basic_block_def.
     (b) the index of a basic_block within the cfg's x_basic_block_info
     vector, as accessed via BASIC_BLOCK_FOR_FN.

     These can get out-of-sync when basic blocks are optimized away.
     They get back in sync by "compact_blocks".
     We reconstruct cfun->cfg->x_basic_block_info->m_vecdata with NULL
     values in it for any missing basic blocks, so that (a) == (b) for
     all of the blocks we create.  The doubly-linked list of basic
     blocks (next_bb/prev_bb) skips over these "holes".  */

  if (m_highest_bb_idx < bb_idx)
    m_highest_bb_idx = bb_idx;

  size_t new_size = m_highest_bb_idx + 1;
  if (basic_block_info_for_fn (cfun)->length () < new_size)
    vec_safe_grow_cleared (basic_block_info_for_fn (cfun), new_size, true);

  last_basic_block_for_fn (cfun) = new_size;

  /* Create the basic block.

     We can't call create_basic_block and use the regular RTL block-creation
     hooks, since this creates NOTE_INSN_BASIC_BLOCK instances.  We don't
     want to do that; we want to use the notes we were provided with.  */
  basic_block bb = alloc_block ();
  init_rtl_bb_info (bb);
  bb->index = bb_idx;
  bb->flags = BB_NEW | BB_RTL;
  link_block (bb, m_bb_to_insert_after);
  m_bb_to_insert_after = bb;

  n_basic_blocks_for_fn (cfun)++;
  SET_BASIC_BLOCK_FOR_FN (cfun, bb_idx, bb);
  BB_SET_PARTITION (bb, BB_UNPARTITIONED);

  /* Handle insns, edge-from and edge-to directives.  */
  while (1)
    {
      int c = read_skip_spaces ();
      file_location loc = get_current_location ();
      if (c == ')')
	break;
      else if (c == '(')
	{
	  struct md_name directive;
	  read_name (&directive);
	  if (strcmp (directive.string, "edge-from") == 0)
	    parse_edge (bb, true);
	  else if (strcmp (directive.string, "edge-to") == 0)
	    parse_edge (bb, false);
	  else
	    {
	      rtx_insn *insn = parse_insn (loc, directive.string);
	      set_block_for_insn (insn, bb);
	      if (!BB_HEAD (bb))
		BB_HEAD (bb) = insn;
	      BB_END (bb) = insn;
	    }
	}
      else
	fatal_at (loc, "expected '(' or ')'");
    }
}

/* Subroutine of function_reader::parse_edge.
   Parse a basic block index, handling "entry" and "exit".  */

int
function_reader::parse_bb_idx ()
{
  struct md_name name;
  read_name (&name);
  if (strcmp (name.string, "entry") == 0)
    return ENTRY_BLOCK;
  if (strcmp (name.string, "exit") == 0)
    return EXIT_BLOCK;
  return atoi (name.string);
}

/* Subroutine of parse_edge_flags.
   Parse TOK, a token such as "FALLTHRU", converting to the flag value.
   Issue an error if the token is unrecognized.  */

static int
parse_edge_flag_token (const char *tok)
{
#define DEF_EDGE_FLAG(NAME,IDX)		\
  do {						\
    if (strcmp (tok, #NAME) == 0)		\
      return EDGE_##NAME; \
  } while (0);
#include "cfg-flags.def"
#undef DEF_EDGE_FLAG
  error ("unrecognized edge flag: %qs", tok);
  return 0;
}

/* Subroutine of function_reader::parse_edge.
   Parse STR and convert to a flag value (or issue an error).
   The parser uses strtok and hence modifiers STR in-place.  */

static int
parse_edge_flags (char *str)
{
  int result = 0;

  char *tok = strtok (str, "| ");
  while (tok)
    {
      result |= parse_edge_flag_token (tok);
      tok = strtok (NULL, "| ");
    }

  return result;
}

/* Parse an "edge-from" or "edge-to" directive within the "block"
   directive for BLOCK, having already parsed the "(edge" heading.
   Consume the final ")".  Record the edge within m_deferred_edges.
   FROM is true for an "edge-from" directive, false for an "edge-to"
   directive.  */

void
function_reader::parse_edge (basic_block block, bool from)
{
  gcc_assert (block);
  int this_bb_idx = block->index;
  file_location loc = get_current_location ();
  int other_bb_idx = parse_bb_idx ();

  /* "(edge-from 2)" means src = 2, dest = this_bb_idx, whereas
     "(edge-to 3)" means src = this_bb_idx, dest = 3.  */
  int src_idx = from ? other_bb_idx : this_bb_idx;
  int dest_idx = from ? this_bb_idx : other_bb_idx;

  /* Optional "(flags)".  */
  int flags = 0;
  int c = read_skip_spaces ();
  if (c == '(')
    {
      require_word_ws ("flags");
      require_char_ws ('"');
      char *str = read_quoted_string ();
      flags = parse_edge_flags (str);
      require_char_ws (')');
    }
  else
    unread_char (c);

  require_char_ws (')');

  /* This BB already exists, but the other BB might not yet.
     For now, save the edges, and create them at the end of insn-chain
     processing. */
  /* For now, only process the (edge-from) to this BB, and (edge-to)
     that go to the exit block.
     FIXME: we don't yet verify that the edge-from and edge-to directives
     are consistent.  */
  if (from || dest_idx == EXIT_BLOCK)
    m_deferred_edges.safe_push (deferred_edge (loc, src_idx, dest_idx, flags));
}

/* Parse an rtx instruction, having parsed the opening and parenthesis, and
   name NAME, seen at START_LOC, by calling read_rtx_code, calling
   set_first_insn and set_last_insn as appropriate, and
   adding the insn to the insn chain.
   Consume the trailing ')'.  */

rtx_insn *
function_reader::parse_insn (file_location start_loc, const char *name)
{
  rtx x = read_rtx_code (name);
  if (!x)
    fatal_at (start_loc, "expected insn type; got '%s'", name);
  rtx_insn *insn = dyn_cast <rtx_insn *> (x);
  if (!insn)
    fatal_at (start_loc, "expected insn type; got '%s'", name);

  /* Consume the trailing ')'.  */
  require_char_ws (')');

  rtx_insn *last_insn = get_last_insn ();

  /* Add "insn" to the insn chain.  */
  if (last_insn)
    {
      gcc_assert (NEXT_INSN (last_insn) == NULL);
      SET_NEXT_INSN (last_insn) = insn;
    }
  SET_PREV_INSN (insn) = last_insn;

  /* Add it to the sequence.  */
  set_last_insn (insn);
  if (!m_first_insn)
    {
      m_first_insn = insn;
      set_first_insn (insn);
    }

  if (rtx_code_label *label = dyn_cast <rtx_code_label *> (insn))
    maybe_set_max_label_num (label);

  return insn;
}

/* Postprocessing subroutine for parse_insn_chain: all the basic blocks
   should have been created by now; create the edges that were seen.  */

void
function_reader::create_edges ()
{
  int i;
  deferred_edge *de;
  FOR_EACH_VEC_ELT (m_deferred_edges, i, de)
    {
      /* The BBs should already have been created by parse_block.  */
      basic_block src = BASIC_BLOCK_FOR_FN (cfun, de->m_src_bb_idx);
      if (!src)
	fatal_at (de->m_loc, "error: block index %i not found",
		  de->m_src_bb_idx);
      basic_block dst = BASIC_BLOCK_FOR_FN (cfun, de->m_dest_bb_idx);
      if (!dst)
	fatal_at (de->m_loc, "error: block with index %i not found",
		  de->m_dest_bb_idx);
      unchecked_make_edge (src, dst, de->m_flags);
    }
}

/* Parse a "crtl" directive, having already parsed the "(crtl" heading
   at location LOC.
   Consume the final ")".  */

void
function_reader::parse_crtl (file_location loc)
{
  if (m_have_crtl_directive)
    error_at (loc, "more than one 'crtl' directive");
  m_have_crtl_directive = true;

  /* return_rtx.  */
  require_char_ws ('(');
  require_word_ws ("return_rtx");
  crtl->return_rtx = parse_rtx ();
  require_char_ws (')');

  require_char_ws (')');
}

/* Parse operand IDX of X, returning X, or an equivalent rtx
   expression (for consolidating singletons).
   This is an overridden implementation of rtx_reader::read_rtx_operand for
   function_reader, handling various extra data printed by print_rtx,
   and sometimes calling the base class implementation.  */

rtx
function_reader::read_rtx_operand (rtx x, int idx)
{
  RTX_CODE code = GET_CODE (x);
  const char *format_ptr = GET_RTX_FORMAT (code);
  const char format_char = format_ptr[idx];
  struct md_name name;

  /* Override the regular parser for some format codes.  */
  switch (format_char)
    {
    case 'e':
      if (idx == 7 && CALL_P (x))
	{
	  m_in_call_function_usage = true;
	  return rtx_reader::read_rtx_operand (x, idx);
	  m_in_call_function_usage = false;
	}
      else
	return rtx_reader::read_rtx_operand (x, idx);
      break;

    case 'u':
      read_rtx_operand_u (x, idx);
      /* Don't run regular parser for 'u'.  */
      return x;

    case 'i':
    case 'n':
      read_rtx_operand_i_or_n (x, idx, format_char);
      /* Don't run regular parser for these codes.  */
      return x;

    case 'B':
      gcc_assert (is_compact ());
      /* Compact mode doesn't store BBs.  */
      /* Don't run regular parser.  */
      return x;

    case 'r':
      /* Don't run regular parser for 'r'.  */
      return read_rtx_operand_r (x);

    default:
      break;
    }

  /* Call base class implementation.  */
  x = rtx_reader::read_rtx_operand (x, idx);

  /* Handle any additional parsing needed to handle what the dump
     could contain.  */
  switch (format_char)
    {
    case '0':
      x = extra_parsing_for_operand_code_0 (x, idx);
      break;

    case 'w':
      if (!is_compact ())
	{
	  /* Strip away the redundant hex dump of the value.  */
	  require_char_ws ('[');
	  read_name (&name);
	  require_char_ws (']');
	}
      break;

    default:
      break;
    }

  return x;
}

/* Parse operand IDX of X, of code 'u', when reading function dumps.

   The RTL file recorded the ID of an insn (or 0 for NULL); we
   must store this as a pointer, but the insn might not have
   been loaded yet.  Store the ID away for now, via a fixup.  */

void
function_reader::read_rtx_operand_u (rtx x, int idx)
{
  /* In compact mode, the PREV/NEXT insn uids are not dumped, so skip
     the "uu" when reading. */
  if (is_compact () && GET_CODE (x) != LABEL_REF)
    return;

  struct md_name name;
  file_location loc = read_name (&name);
  int insn_id = atoi (name.string);
  if (insn_id)
    add_fixup_insn_uid (loc, x, idx, insn_id);
}

/* Read a name, looking for a match against a string found in array
   STRINGS of size NUM_VALUES.
   Return the index of the matched string, or emit an error.  */

int
function_reader::parse_enum_value (int num_values, const char *const *strings)
{
  struct md_name name;
  read_name (&name);
  for (int i = 0; i < num_values; i++)
    {
      if (strcmp (name.string, strings[i]) == 0)
	return i;
    }
  error ("unrecognized enum value: %qs", name.string);
  return 0;
}

/* Parse operand IDX of X, of code 'i' or 'n' (as specified by FORMAT_CHAR).
   Special-cased handling of these, for reading function dumps.  */

void
function_reader::read_rtx_operand_i_or_n (rtx x, int idx,
					  char format_char)
{
  /* Handle some of the extra information that print_rtx
     can write out for these cases.  */
  /* print_rtx only writes out operand 5 for notes
     for NOTE_KIND values NOTE_INSN_DELETED_LABEL
     and NOTE_INSN_DELETED_DEBUG_LABEL.  */
  if (idx == 5 && NOTE_P (x))
    return;

  if (idx == 4 && INSN_P (x))
    {
      maybe_read_location (as_a <rtx_insn *> (x));
      return;
    }

  /* INSN_CODEs aren't printed in compact mode, so don't attempt to
     parse them.  */
  if (is_compact ()
      && INSN_P (x)
      && &INSN_CODE (x) == &XINT (x, idx))
    {
      INSN_CODE (x) = -1;
      return;
    }

  /* Handle UNSPEC and UNSPEC_VOLATILE's operand 1.  */
#if !defined(GENERATOR_FILE) && NUM_UNSPECV_VALUES > 0
  if (idx == 1
      && GET_CODE (x) == UNSPEC_VOLATILE)
    {
      XINT (x, 1)
	= parse_enum_value (NUM_UNSPECV_VALUES, unspecv_strings);
      return;
    }
#endif
#if !defined(GENERATOR_FILE) && NUM_UNSPEC_VALUES > 0
  if (idx == 1
      && (GET_CODE (x) == UNSPEC
	  || GET_CODE (x) == UNSPEC_VOLATILE))
    {
      XINT (x, 1)
	= parse_enum_value (NUM_UNSPEC_VALUES, unspec_strings);
      return;
    }
#endif

  struct md_name name;
  read_name (&name);
  int value;
  if (format_char == 'n')
    value = parse_note_insn_name (name.string);
  else
    value = atoi (name.string);
  XINT (x, idx) = value;
}

/* Parse the 'r' operand of X, returning X, or an equivalent rtx
   expression (for consolidating singletons).
   Special-cased handling of code 'r' for reading function dumps.  */

rtx
function_reader::read_rtx_operand_r (rtx x)
{
  struct md_name name;
  file_location loc = read_name (&name);
  int regno = lookup_reg_by_dump_name (name.string);
  if (regno == -1)
    fatal_at (loc, "unrecognized register: '%s'", name.string);

  set_regno_raw (x, regno, 1);

  /* Consolidate singletons.  */
  x = consolidate_singletons (x);

  ORIGINAL_REGNO (x) = regno;

  /* Parse extra stuff at end of 'r'.
     We may have zero, one, or two sections marked by square
     brackets.  */
  int ch = read_skip_spaces ();
  bool expect_original_regno = false;
  if (ch == '[')
    {
      file_location loc = get_current_location ();
      char *desc = read_until ("]", true);
      strip_trailing_whitespace (desc);
      const char *desc_start = desc;
      /* If ORIGINAL_REGNO (rtx) != regno, we will have:
	 "orig:%i", ORIGINAL_REGNO (rtx).
	 Consume it, we don't set ORIGINAL_REGNO, since we can
	 get that from the 2nd copy later.  */
      if (strncmp (desc, "orig:", 5) == 0)
	{
	  expect_original_regno = true;
	  desc_start += 5;
	  /* Skip to any whitespace following the integer.  */
	  const char *space = strchr (desc_start, ' ');
	  if (space)
	    desc_start = space + 1;
	}
      /* Any remaining text may be the REG_EXPR.  Alternatively we have
	 no REG_ATTRS, and instead we have ORIGINAL_REGNO.  */
      if (ISDIGIT (*desc_start))
	{
	  /* Assume we have ORIGINAL_REGNO.  */
	  ORIGINAL_REGNO (x) = atoi (desc_start);
	}
      else
	{
	  /* Assume we have REG_EXPR.  */
	  add_fixup_expr (loc, x, desc_start);
	}
      free (desc);
    }
  else
    unread_char (ch);
  if (expect_original_regno)
    {
      require_char_ws ('[');
      char *desc = read_until ("]", true);
      ORIGINAL_REGNO (x) = atoi (desc);
      free (desc);
    }

  return x;
}

/* Additional parsing for format code '0' in dumps, handling a variety
   of special-cases in print_rtx, when parsing operand IDX of X.
   Return X, or possibly a reallocated copy of X.  */

rtx
function_reader::extra_parsing_for_operand_code_0 (rtx x, int idx)
{
  RTX_CODE code = GET_CODE (x);
  int c;
  struct md_name name;

  if (idx == 1 && code == SYMBOL_REF)
    {
      /* Possibly wrote " [flags %#x]", SYMBOL_REF_FLAGS (in_rtx).  */
      c = read_skip_spaces ();
      if (c == '[')
	{
	  file_location loc = read_name (&name);
	  if (strcmp (name.string, "flags"))
	    error_at (loc, "was expecting `%s'", "flags");
	  read_name (&name);
	  SYMBOL_REF_FLAGS (x) = strtol (name.string, NULL, 16);

	  /* The standard RTX_CODE_SIZE (SYMBOL_REF) used when allocating
	     x doesn't have space for the block_symbol information, so
	     we must reallocate it if this flag is set.  */
	  if (SYMBOL_REF_HAS_BLOCK_INFO_P (x))
	    {
	      /* Emulate the allocation normally done by
		 varasm.c:create_block_symbol.  */
	      unsigned int size = RTX_HDR_SIZE + sizeof (struct block_symbol);
	      rtx new_x = (rtx) ggc_internal_alloc (size);

	      /* Copy data over from the smaller SYMBOL_REF.  */
	      memcpy (new_x, x, RTX_CODE_SIZE (SYMBOL_REF));
	      x = new_x;

	      /* We can't reconstruct SYMBOL_REF_BLOCK; set it to NULL.  */
	      SYMBOL_REF_BLOCK (x) = NULL;

	      /* Zero the offset.  */
	      SYMBOL_REF_BLOCK_OFFSET (x) = 0;
	    }

	  require_char (']');
	}
      else
	unread_char (c);

      /* If X had a non-NULL SYMBOL_REF_DECL,
	 rtx_writer::print_rtx_operand_code_0 would have dumped it
	 using print_node_brief.
	 Skip the content for now.  */
      c = read_skip_spaces ();
      if (c == '<')
	{
	  while (1)
	    {
	      char ch = read_char ();
	      if (ch == '>')
		break;
	    }
	}
      else
	unread_char (c);
    }
  else if (idx == 3 && code == NOTE)
    {
      /* Note-specific data appears for operand 3, which annoyingly
	 is before the enum specifying which kind of note we have
	 (operand 4).  */
      c = read_skip_spaces ();
      if (c == '[')
	{
	  /* Possibly data for a NOTE_INSN_BASIC_BLOCK, of the form:
	     [bb %d].  */
	  file_location bb_loc = read_name (&name);
	  if (strcmp (name.string, "bb"))
	    error_at (bb_loc, "was expecting `%s'", "bb");
	  read_name (&name);
	  int bb_idx = atoi (name.string);
	  add_fixup_note_insn_basic_block (bb_loc, x, idx,
					   bb_idx);
	  require_char_ws (']');
	}
      else
	unread_char (c);
    }

  return x;
}

/* Implementation of rtx_reader::handle_any_trailing_information.
   Handle the various additional information that print-rtl.c can
   write after the regular fields, when parsing X.  */

void
function_reader::handle_any_trailing_information (rtx x)
{
  struct md_name name;

  switch (GET_CODE (x))
    {
      case MEM:
	{
	  int ch;
	  require_char_ws ('[');
	  read_name (&name);
	  set_mem_alias_set (x, atoi (name.string));
	  /* We have either a MEM_EXPR, or a space.  */
	  if (peek_char () != ' ')
	    {
	      file_location loc = get_current_location ();
	      char *desc = read_until (" +", false);
	      add_fixup_expr (loc, consolidate_singletons (x), desc);
	      free (desc);
	    }
	  else
	    read_char ();

	  /* We may optionally have '+' for MEM_OFFSET_KNOWN_P.  */
	  ch = read_skip_spaces ();
	  if (ch == '+')
	    {
	      read_name (&name);
	      set_mem_offset (x, atoi (name.string));
	    }
	  else
	    unread_char (ch);

	  /* Handle optional " S" for MEM_SIZE.  */
	  ch = read_skip_spaces ();
	  if (ch == 'S')
	    {
	      read_name (&name);
	      set_mem_size (x, atoi (name.string));
	    }
	  else
	    unread_char (ch);

	  /* Handle optional " A" for MEM_ALIGN.  */
	  ch = read_skip_spaces ();
	  if (ch == 'A' && peek_char () != 'S')
	    {
	      read_name (&name);
	      set_mem_align (x, atoi (name.string));
	    }
	  else
	    unread_char (ch);

	  /* Handle optional " AS" for MEM_ADDR_SPACE.  */
	  ch = read_skip_spaces ();
	  if (ch == 'A' && peek_char () == 'S')
	    {
	      read_char ();
	      read_name (&name);
	      set_mem_addr_space (x, atoi (name.string));
	    }
	  else
	    unread_char (ch);

	  require_char (']');
	}
	break;

      case CODE_LABEL:
	/* Assume that LABEL_NUSES was not dumped.  */
	/* TODO: parse LABEL_KIND.  */
	/* For now, skip until closing ')'.  */
	do
	  {
	    char ch = read_char ();
	    if (ch == ')')
	      {
		unread_char (ch);
		break;
	      }
	  }
	while (1);
	break;

      default:
	break;
    }
}

/* Parse a tree dump for a MEM_EXPR in DESC and turn it back into a tree.
   We handle "<retval>" and param names within cfun, but for anything else
   we "cheat" by building a global VAR_DECL of type "int" with that name
   (returning the same global for a name if we see the same name more
   than once).  */

tree
function_reader::parse_mem_expr (const char *desc)
{
  tree fndecl = cfun->decl;

  if (strcmp (desc, "<retval>") == 0)
    return DECL_RESULT (fndecl);

  tree param = find_param_by_name (fndecl, desc);
  if (param)
    return param;

  /* Search within decls we already created.
     FIXME: use a hash rather than linear search.  */
  int i;
  tree t;
  FOR_EACH_VEC_ELT (m_fake_scope, i, t)
    if (id_equal (DECL_NAME (t), desc))
      return t;

  /* Not found?  Create it.
     This allows mimicking of real data but avoids having to specify
     e.g. names of locals, params etc.
     Though this way we don't know if we have a PARM_DECL vs a VAR_DECL,
     and we don't know the types.  Fake it by making everything be
     a VAR_DECL of "int" type.  */
  t = build_decl (UNKNOWN_LOCATION, VAR_DECL,
		  get_identifier (desc),
		  integer_type_node);
  m_fake_scope.safe_push (t);
  return t;
}

/* Record that at LOC we saw an insn uid INSN_UID for the operand with index
   OPERAND_IDX within INSN, so that the pointer value can be fixed up in
   later post-processing.  */

void
function_reader::add_fixup_insn_uid (file_location loc, rtx insn, int operand_idx,
				     int insn_uid)
{
  m_fixups.safe_push (new fixup_insn_uid (loc, insn, operand_idx, insn_uid));
}

/* Record that at LOC we saw an basic block index BB_IDX for the operand with index
   OPERAND_IDX within INSN, so that the pointer value can be fixed up in
   later post-processing.  */

void
function_reader::add_fixup_note_insn_basic_block (file_location loc, rtx insn,
						  int operand_idx, int bb_idx)
{
  m_fixups.safe_push (new fixup_note_insn_basic_block (loc, insn, operand_idx,
						       bb_idx));
}

/* Placeholder hook for recording source location information seen in a dump.
   This is empty for now.  */

void
function_reader::add_fixup_source_location (file_location, rtx_insn *,
					    const char *, int, int)
{
}

/* Record that at LOC we saw textual description DESC of the MEM_EXPR or REG_EXPR
   of INSN, so that the fields can be fixed up in later post-processing.  */

void
function_reader::add_fixup_expr (file_location loc, rtx insn,
				 const char *desc)
{
  gcc_assert (desc);
  /* Fail early if the RTL reader erroneously hands us an int.  */
  gcc_assert (!ISDIGIT (desc[0]));

  m_fixups.safe_push (new fixup_expr (loc, insn, desc));
}

/* Helper function for consolidate_reg.  Return the global rtx for
   the register with regno REGNO.  */

static rtx
lookup_global_register (int regno)
{
  /* We can't use a switch here, as some of the REGNUMs might not be constants
     for some targets.  */
  if (regno == STACK_POINTER_REGNUM)
      return stack_pointer_rtx;
  else if (regno ==  FRAME_POINTER_REGNUM)
    return frame_pointer_rtx;
  else if (regno == HARD_FRAME_POINTER_REGNUM)
    return hard_frame_pointer_rtx;
  else if (regno == ARG_POINTER_REGNUM)
    return arg_pointer_rtx;
  else if (regno == VIRTUAL_INCOMING_ARGS_REGNUM)
    return virtual_incoming_args_rtx;
  else if (regno == VIRTUAL_STACK_VARS_REGNUM)
    return virtual_stack_vars_rtx;
  else if (regno == VIRTUAL_STACK_DYNAMIC_REGNUM)
    return virtual_stack_dynamic_rtx;
  else if (regno == VIRTUAL_OUTGOING_ARGS_REGNUM)
    return virtual_outgoing_args_rtx;
  else if (regno == VIRTUAL_CFA_REGNUM)
    return virtual_cfa_rtx;
  else if (regno == VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM)
    return virtual_preferred_stack_boundary_rtx;
#ifdef return_ADDRESS_POINTER_REGNUM
  else if (regno == RETURN_ADDRESS_POINTER_REGNUM)
    return return_address_pointer_rtx;
#endif

  return NULL;
}

/* Ensure that the backend can cope with a REG with regno REGNO.
   Normally REG instances are created by gen_reg_rtx which updates
   regno_reg_rtx, growing it as necessary.
   The REG instances created from the dumpfile weren't created this
   way, so we need to manually update regno_reg_rtx.  */

static void
ensure_regno (int regno)
{
  if (reg_rtx_no < regno + 1)
    reg_rtx_no = regno + 1;

  crtl->emit.ensure_regno_capacity ();
  gcc_assert (regno < crtl->emit.regno_pointer_align_length);
}

/* Helper function for consolidate_singletons, for handling REG instances.
   Given REG instance X of some regno, return the singleton rtx for that
   regno, if it exists, or X.  */

static rtx
consolidate_reg (rtx x)
{
  gcc_assert (GET_CODE (x) == REG);

  unsigned int regno = REGNO (x);

  ensure_regno (regno);

  /* Some register numbers have their rtx created in init_emit_regs
     e.g. stack_pointer_rtx for STACK_POINTER_REGNUM.
     Consolidate on this.  */
  rtx global_reg = lookup_global_register (regno);
  if (global_reg)
    return global_reg;

  /* Populate regno_reg_rtx if necessary.  */
  if (regno_reg_rtx[regno] == NULL)
    regno_reg_rtx[regno] = x;
  /* Use it.  */
  gcc_assert (GET_CODE (regno_reg_rtx[regno]) == REG);
  gcc_assert (REGNO (regno_reg_rtx[regno]) == regno);
  if (GET_MODE (x) == GET_MODE (regno_reg_rtx[regno]))
    return regno_reg_rtx[regno];

  return x;
}

/* When reading RTL function dumps, we must consolidate some
   rtx so that we use singletons where singletons are expected
   (e.g. we don't want multiple "(const_int 0 [0])" rtx, since
   these are tested via pointer equality against const0_rtx.

   Return the equivalent singleton rtx for X, if any, otherwise X.  */

rtx
function_reader::consolidate_singletons (rtx x)
{
  if (!x)
    return x;

  switch (GET_CODE (x))
    {
    case PC: return pc_rtx;
    case RETURN: return ret_rtx;
    case SIMPLE_RETURN: return simple_return_rtx;
    case CC0: return cc0_rtx;

    case REG:
      return consolidate_reg (x);

    case CONST_INT:
      return gen_rtx_CONST_INT (GET_MODE (x), INTVAL (x));

    default:
      break;
    }

  return x;
}

/* Parse an rtx directive, including both the opening/closing parentheses,
   and the name.  */

rtx
function_reader::parse_rtx ()
{
  require_char_ws ('(');
  struct md_name directive;
  read_name (&directive);
  rtx result
    = consolidate_singletons (read_rtx_code (directive.string));
  require_char_ws (')');

  return result;
}

/* Implementation of rtx_reader::postprocess for reading function dumps.
   Return the equivalent singleton rtx for X, if any, otherwise X.  */

rtx
function_reader::postprocess (rtx x)
{
  return consolidate_singletons (x);
}

/* Implementation of rtx_reader::finalize_string for reading function dumps.
   Make a GC-managed copy of STRINGBUF.  */

const char *
function_reader::finalize_string (char *stringbuf)
{
  return ggc_strdup (stringbuf);
}

/* Attempt to parse optional location information for insn INSN, as
   potentially written out by rtx_writer::print_rtx_operand_code_i.
   We look for a quoted string followed by a colon.  */

void
function_reader::maybe_read_location (rtx_insn *insn)
{
  file_location loc = get_current_location ();

  /* Attempt to parse a quoted string.  */
  int ch = read_skip_spaces ();
  if (ch == '"')
    {
      char *filename = read_quoted_string ();
      require_char (':');
      struct md_name line_num;
      read_name (&line_num);

      int column = 0;
      int ch = read_char ();
      if (ch == ':')
	{
	  struct md_name column_num;
	  read_name (&column_num);
	  column = atoi (column_num.string);
	}
      else
	unread_char (ch);
      add_fixup_source_location (loc, insn, filename,
				 atoi (line_num.string),
				 column);
    }
  else
    unread_char (ch);
}

/* Postprocessing subroutine of function_reader::parse_function.
   Populate m_insns_by_uid.  */

void
function_reader::handle_insn_uids ()
{
  /* Locate the currently assigned INSN_UID values, storing
     them in m_insns_by_uid.  */
  int max_uid = 0;
  for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
    {
      if (m_insns_by_uid.get (INSN_UID (insn)))
	error ("duplicate insn UID: %i", INSN_UID (insn));
      m_insns_by_uid.put (INSN_UID (insn), insn);
      if (INSN_UID (insn) > max_uid)
	max_uid = INSN_UID (insn);
    }

  /* Ensure x_cur_insn_uid is 1 more than the biggest insn UID seen.
     This is normally updated by the various make_*insn_raw functions.  */
  crtl->emit.x_cur_insn_uid = max_uid + 1;
}

/* Apply all of the recorded fixups.  */

void
function_reader::apply_fixups ()
{
  int i;
  fixup *f;
  FOR_EACH_VEC_ELT (m_fixups, i, f)
    f->apply (this);
}

/* Given a UID value, try to locate a pointer to the corresponding
   rtx_insn *, or NULL if it can't be found.  */

rtx_insn **
function_reader::get_insn_by_uid (int uid)
{
  return m_insns_by_uid.get (uid);
}

/* Run the RTL dump parser, parsing a dump located at PATH.
   Return true iff the file was successfully parsed.  */

bool
read_rtl_function_body (const char *path)
{
  initialize_rtl ();
  crtl->abi = &default_function_abi;
  init_emit ();
  init_varasm_status ();

  function_reader reader;
  if (!reader.read_file (path))
    return false;

  return true;
}

/* Run the RTL dump parser on the range of lines between START_LOC and
   END_LOC (including those lines).  */

bool
read_rtl_function_body_from_file_range (location_t start_loc,
					location_t end_loc)
{
  expanded_location exploc_start = expand_location (start_loc);
  expanded_location exploc_end = expand_location (end_loc);

  if (exploc_start.file != exploc_end.file)
    {
      error_at (end_loc, "start/end of RTL fragment are in different files");
      return false;
    }
  if (exploc_start.line >= exploc_end.line)
    {
      error_at (end_loc,
		"start of RTL fragment must be on an earlier line than end");
      return false;
    }

  initialize_rtl ();
  crtl->abi = &fndecl_abi (cfun->decl).base_abi ();
  init_emit ();
  init_varasm_status ();

  function_reader reader;
  if (!reader.read_file_fragment (exploc_start.file, exploc_start.line,
				  exploc_end.line - 1))
    return false;

  return true;
}

#if CHECKING_P

namespace selftest {

/* Verify that parse_edge_flags works.  */

static void
test_edge_flags ()
{
  /* parse_edge_flags modifies its input (due to strtok), so we must make
     a copy of the literals.  */
#define ASSERT_PARSE_EDGE_FLAGS(EXPECTED, STR) \
  do { \
    char *str = xstrdup (STR); \
    ASSERT_EQ (EXPECTED, parse_edge_flags (str)); \
    free (str); \
  } while (0)

  ASSERT_PARSE_EDGE_FLAGS (0, "");
  ASSERT_PARSE_EDGE_FLAGS (EDGE_FALLTHRU, "FALLTHRU");
  ASSERT_PARSE_EDGE_FLAGS (EDGE_ABNORMAL_CALL, "ABNORMAL_CALL");
  ASSERT_PARSE_EDGE_FLAGS (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL,
			   "ABNORMAL | ABNORMAL_CALL");

#undef  ASSERT_PARSE_EDGE_FLAGS
}

/* Verify that lookup_reg_by_dump_name works.  */

static void
test_parsing_regnos ()
{
  ASSERT_EQ (-1, lookup_reg_by_dump_name ("this is not a register"));

  /* Verify lookup of virtual registers.  */
  ASSERT_EQ (VIRTUAL_INCOMING_ARGS_REGNUM,
    lookup_reg_by_dump_name ("virtual-incoming-args"));
  ASSERT_EQ (VIRTUAL_STACK_VARS_REGNUM,
    lookup_reg_by_dump_name ("virtual-stack-vars"));
  ASSERT_EQ (VIRTUAL_STACK_DYNAMIC_REGNUM,
    lookup_reg_by_dump_name ("virtual-stack-dynamic"));
  ASSERT_EQ (VIRTUAL_OUTGOING_ARGS_REGNUM,
    lookup_reg_by_dump_name ("virtual-outgoing-args"));
  ASSERT_EQ (VIRTUAL_CFA_REGNUM,
    lookup_reg_by_dump_name ("virtual-cfa"));
  ASSERT_EQ (VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM,
    lookup_reg_by_dump_name ("virtual-preferred-stack-boundary"));

  /* Verify lookup of non-virtual pseudos.  */
  ASSERT_EQ (LAST_VIRTUAL_REGISTER + 1, lookup_reg_by_dump_name ("<0>"));
  ASSERT_EQ (LAST_VIRTUAL_REGISTER + 2, lookup_reg_by_dump_name ("<1>"));
}

/* Verify that edge E is as expected, with the src and dest basic blocks
   having indices EXPECTED_SRC_IDX and EXPECTED_DEST_IDX respectively, and
   the edge having flags equal to EXPECTED_FLAGS.
   Use LOC as the effective location when reporting failures.  */

static void
assert_edge_at (const location &loc, edge e, int expected_src_idx,
		int expected_dest_idx, int expected_flags)
{
  ASSERT_EQ_AT (loc, expected_src_idx, e->src->index);
  ASSERT_EQ_AT (loc, expected_dest_idx, e->dest->index);
  ASSERT_EQ_AT (loc, expected_flags, e->flags);
}

/* Verify that edge EDGE is as expected, with the src and dest basic blocks
   having indices EXPECTED_SRC_IDX and EXPECTED_DEST_IDX respectively, and
   the edge having flags equal to EXPECTED_FLAGS.  */

#define ASSERT_EDGE(EDGE, EXPECTED_SRC_IDX, EXPECTED_DEST_IDX,		\
		    EXPECTED_FLAGS)					\
  assert_edge_at (SELFTEST_LOCATION, EDGE, EXPECTED_SRC_IDX, \
		  EXPECTED_DEST_IDX, EXPECTED_FLAGS)

/* Verify that we can load RTL dumps.  */

static void
test_loading_dump_fragment_1 ()
{
  // TODO: filter on target?
  rtl_dump_test t (SELFTEST_LOCATION, locate_file ("asr_div1.rtl"));

  /* Verify that the insns were loaded correctly.  */
  rtx_insn *insn_1 = get_insns ();
  ASSERT_TRUE (insn_1);
  ASSERT_EQ (1, INSN_UID (insn_1));
  ASSERT_EQ (INSN, GET_CODE (insn_1));
  ASSERT_EQ (SET, GET_CODE (PATTERN (insn_1)));
  ASSERT_EQ (NULL, PREV_INSN (insn_1));

  rtx_insn *insn_2 = NEXT_INSN (insn_1);
  ASSERT_TRUE (insn_2);
  ASSERT_EQ (2, INSN_UID (insn_2));
  ASSERT_EQ (INSN, GET_CODE (insn_2));
  ASSERT_EQ (insn_1, PREV_INSN (insn_2));
  ASSERT_EQ (NULL, NEXT_INSN (insn_2));

  /* Verify that registers were loaded correctly.  */
  rtx insn_1_dest = SET_DEST (PATTERN (insn_1));
  ASSERT_EQ (REG, GET_CODE (insn_1_dest));
  ASSERT_EQ ((LAST_VIRTUAL_REGISTER + 1) + 2, REGNO (insn_1_dest));
  rtx insn_1_src = SET_SRC (PATTERN (insn_1));
  ASSERT_EQ (LSHIFTRT, GET_CODE (insn_1_src));
  rtx reg = XEXP (insn_1_src, 0);
  ASSERT_EQ (REG, GET_CODE (reg));
  ASSERT_EQ (LAST_VIRTUAL_REGISTER + 1, REGNO (reg));

  /* Verify that get_insn_by_uid works.  */
  ASSERT_EQ (insn_1, get_insn_by_uid (1));
  ASSERT_EQ (insn_2, get_insn_by_uid (2));

  /* Verify that basic blocks were created.  */
  ASSERT_EQ (2, BLOCK_FOR_INSN (insn_1)->index);
  ASSERT_EQ (2, BLOCK_FOR_INSN (insn_2)->index);

  /* Verify that the CFG was recreated.  */
  ASSERT_TRUE (cfun);
  verify_three_block_rtl_cfg (cfun);
  basic_block bb2 = BASIC_BLOCK_FOR_FN (cfun, 2);
  ASSERT_TRUE (bb2 != NULL);
  ASSERT_EQ (BB_RTL, bb2->flags & BB_RTL);
  ASSERT_EQ (2, bb2->index);
  ASSERT_EQ (insn_1, BB_HEAD (bb2));
  ASSERT_EQ (insn_2, BB_END (bb2));
}

/* Verify loading another RTL dump.  */

static void
test_loading_dump_fragment_2 ()
{
  rtl_dump_test t (SELFTEST_LOCATION, locate_file ("simple-cse.rtl"));

  rtx_insn *insn_1 = get_insn_by_uid (1);
  rtx_insn *insn_2 = get_insn_by_uid (2);
  rtx_insn *insn_3 = get_insn_by_uid (3);

  rtx set1 = single_set (insn_1);
  ASSERT_NE (NULL, set1);
  rtx set2 = single_set (insn_2);
  ASSERT_NE (NULL, set2);
  rtx set3 = single_set (insn_3);
  ASSERT_NE (NULL, set3);

  rtx src1 = SET_SRC (set1);
  ASSERT_EQ (PLUS, GET_CODE (src1));

  rtx src2 = SET_SRC (set2);
  ASSERT_EQ (PLUS, GET_CODE (src2));

  /* Both src1 and src2 refer to "(reg:SI %0)".
     Verify that we have pointer equality.  */
  rtx lhs1 = XEXP (src1, 0);
  rtx lhs2 = XEXP (src2, 0);
  ASSERT_EQ (lhs1, lhs2);

  /* Verify that the CFG was recreated. */
  ASSERT_TRUE (cfun);
  verify_three_block_rtl_cfg (cfun);
}

/* Verify that CODE_LABEL insns are loaded correctly.  */

static void
test_loading_labels ()
{
  rtl_dump_test t (SELFTEST_LOCATION, locate_file ("example-labels.rtl"));

  rtx_insn *insn_100 = get_insn_by_uid (100);
  ASSERT_EQ (CODE_LABEL, GET_CODE (insn_100));
  ASSERT_EQ (100, INSN_UID (insn_100));
  ASSERT_EQ (NULL, LABEL_NAME (insn_100));
  ASSERT_EQ (0, LABEL_NUSES (insn_100));
  ASSERT_EQ (30, CODE_LABEL_NUMBER (insn_100));

  rtx_insn *insn_200 = get_insn_by_uid (200);
  ASSERT_EQ (CODE_LABEL, GET_CODE (insn_200));
  ASSERT_EQ (200, INSN_UID (insn_200));
  ASSERT_STREQ ("some_label_name", LABEL_NAME (insn_200));
  ASSERT_EQ (0, LABEL_NUSES (insn_200));
  ASSERT_EQ (40, CODE_LABEL_NUMBER (insn_200));

  /* Ensure that the presence of CODE_LABEL_NUMBER == 40
     means that the next label num to be handed out will be 41.  */
  ASSERT_EQ (41, max_label_num ());

  /* Ensure that label names read from a dump are GC-managed
     and are found through the insn.  */
  forcibly_ggc_collect ();
  ASSERT_TRUE (ggc_marked_p (insn_200));
  ASSERT_TRUE (ggc_marked_p (LABEL_NAME (insn_200)));
}

/* Verify that the loader copes with an insn with a mode.  */

static void
test_loading_insn_with_mode ()
{
  rtl_dump_test t (SELFTEST_LOCATION, locate_file ("insn-with-mode.rtl"));
  rtx_insn *insn = get_insns ();
  ASSERT_EQ (INSN, GET_CODE (insn));

  /* Verify that the "TI" mode was set from "insn:TI".  */
  ASSERT_EQ (TImode, GET_MODE (insn));
}

/* Verify that the loader copes with a jump_insn to a label_ref.  */

static void
test_loading_jump_to_label_ref ()
{
  rtl_dump_test t (SELFTEST_LOCATION, locate_file ("jump-to-label-ref.rtl"));

  rtx_insn *jump_insn = get_insn_by_uid (1);
  ASSERT_EQ (JUMP_INSN, GET_CODE (jump_insn));

  rtx_insn *barrier = get_insn_by_uid (2);
  ASSERT_EQ (BARRIER, GET_CODE (barrier));

  rtx_insn *code_label = get_insn_by_uid (100);
  ASSERT_EQ (CODE_LABEL, GET_CODE (code_label));

  /* Verify the jump_insn. */
  ASSERT_EQ (4, BLOCK_FOR_INSN (jump_insn)->index);
  ASSERT_EQ (SET, GET_CODE (PATTERN (jump_insn)));
  /* Ensure that the "(pc)" is using the global singleton.  */
  ASSERT_RTX_PTR_EQ (pc_rtx, SET_DEST (PATTERN (jump_insn)));
  rtx label_ref = SET_SRC (PATTERN (jump_insn));
  ASSERT_EQ (LABEL_REF, GET_CODE (label_ref));
  ASSERT_EQ (code_label, label_ref_label (label_ref));
  ASSERT_EQ (code_label, JUMP_LABEL (jump_insn));

  /* Verify the code_label. */
  ASSERT_EQ (5, BLOCK_FOR_INSN (code_label)->index);
  ASSERT_EQ (NULL, LABEL_NAME (code_label));
  ASSERT_EQ (1, LABEL_NUSES (code_label));

  /* Verify the generated CFG.  */

  /* Locate blocks.  */
  basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (cfun);
  ASSERT_TRUE (entry != NULL);
  ASSERT_EQ (ENTRY_BLOCK, entry->index);

  basic_block exit = EXIT_BLOCK_PTR_FOR_FN (cfun);
  ASSERT_TRUE (exit != NULL);
  ASSERT_EQ (EXIT_BLOCK, exit->index);

  basic_block bb4 = (*cfun->cfg->x_basic_block_info)[4];
  basic_block bb5 = (*cfun->cfg->x_basic_block_info)[5];
  ASSERT_EQ (4, bb4->index);
  ASSERT_EQ (5, bb5->index);

  /* Entry block.  */
  ASSERT_EQ (NULL, entry->preds);
  ASSERT_EQ (1, entry->succs->length ());
  ASSERT_EDGE ((*entry->succs)[0], 0, 4, EDGE_FALLTHRU);

  /* bb4.  */
  ASSERT_EQ (1, bb4->preds->length ());
  ASSERT_EDGE ((*bb4->preds)[0], 0, 4, EDGE_FALLTHRU);
  ASSERT_EQ (1, bb4->succs->length ());
  ASSERT_EDGE ((*bb4->succs)[0], 4, 5, 0x0);

  /* bb5.  */
  ASSERT_EQ (1, bb5->preds->length ());
  ASSERT_EDGE ((*bb5->preds)[0], 4, 5, 0x0);
  ASSERT_EQ (1, bb5->succs->length ());
  ASSERT_EDGE ((*bb5->succs)[0], 5, 1, EDGE_FALLTHRU);

  /* Exit block.  */
  ASSERT_EQ (1, exit->preds->length ());
  ASSERT_EDGE ((*exit->preds)[0], 5, 1, EDGE_FALLTHRU);
  ASSERT_EQ (NULL, exit->succs);
}

/* Verify that the loader copes with a jump_insn to a label_ref
   marked "return".  */

static void
test_loading_jump_to_return ()
{
  rtl_dump_test t (SELFTEST_LOCATION, locate_file ("jump-to-return.rtl"));

  rtx_insn *jump_insn = get_insn_by_uid (1);
  ASSERT_EQ (JUMP_INSN, GET_CODE (jump_insn));
  ASSERT_RTX_PTR_EQ (ret_rtx, JUMP_LABEL (jump_insn));
}

/* Verify that the loader copes with a jump_insn to a label_ref
   marked "simple_return".  */

static void
test_loading_jump_to_simple_return ()
{
  rtl_dump_test t (SELFTEST_LOCATION,
		   locate_file ("jump-to-simple-return.rtl"));

  rtx_insn *jump_insn = get_insn_by_uid (1);
  ASSERT_EQ (JUMP_INSN, GET_CODE (jump_insn));
  ASSERT_RTX_PTR_EQ (simple_return_rtx, JUMP_LABEL (jump_insn));
}

/* Verify that the loader copes with a NOTE_INSN_BASIC_BLOCK.  */

static void
test_loading_note_insn_basic_block ()
{
  rtl_dump_test t (SELFTEST_LOCATION,
		   locate_file ("note_insn_basic_block.rtl"));

  rtx_insn *note = get_insn_by_uid (1);
  ASSERT_EQ (NOTE, GET_CODE (note));
  ASSERT_EQ (2, BLOCK_FOR_INSN (note)->index);

  ASSERT_EQ (NOTE_INSN_BASIC_BLOCK, NOTE_KIND (note));
  ASSERT_EQ (2, NOTE_BASIC_BLOCK (note)->index);
  ASSERT_EQ (BASIC_BLOCK_FOR_FN (cfun, 2), NOTE_BASIC_BLOCK (note));
}

/* Verify that the loader copes with a NOTE_INSN_DELETED.  */

static void
test_loading_note_insn_deleted ()
{
  rtl_dump_test t (SELFTEST_LOCATION, locate_file ("note-insn-deleted.rtl"));

  rtx_insn *note = get_insn_by_uid (1);
  ASSERT_EQ (NOTE, GET_CODE (note));
  ASSERT_EQ (NOTE_INSN_DELETED, NOTE_KIND (note));
}

/* Verify that the const_int values are consolidated, since
   pointer equality corresponds to value equality.
   TODO: do this for all in CASE_CONST_UNIQUE.  */

static void
test_loading_const_int ()
{
  rtl_dump_test t (SELFTEST_LOCATION, locate_file ("const-int.rtl"));

  /* Verify that const_int values below MAX_SAVED_CONST_INT use
     the global values.  */
  ASSERT_EQ (const0_rtx, SET_SRC (PATTERN (get_insn_by_uid (1))));
  ASSERT_EQ (const1_rtx, SET_SRC (PATTERN (get_insn_by_uid (2))));
  ASSERT_EQ (constm1_rtx, SET_SRC (PATTERN (get_insn_by_uid (3))));

  /* Verify that other const_int values are consolidated. */
  rtx int256 = gen_rtx_CONST_INT (SImode, 256);
  ASSERT_EQ (int256, SET_SRC (PATTERN (get_insn_by_uid (4))));
}

/* Verify that the loader copes with a SYMBOL_REF.  */

static void
test_loading_symbol_ref ()
{
  rtl_dump_test t (SELFTEST_LOCATION, locate_file ("symbol-ref.rtl"));

  rtx_insn *insn = get_insns ();

  rtx high = SET_SRC (PATTERN (insn));
  ASSERT_EQ (HIGH, GET_CODE (high));

  rtx symbol_ref = XEXP (high, 0);
  ASSERT_EQ (SYMBOL_REF, GET_CODE (symbol_ref));

  /* Verify that "[flags 0xc0]" was parsed.  */
  ASSERT_EQ (0xc0, SYMBOL_REF_FLAGS (symbol_ref));
  /* TODO: we don't yet load SYMBOL_REF_DECL.  */
}

/* Verify that the loader can rebuild a CFG.  */

static void
test_loading_cfg ()
{
  rtl_dump_test t (SELFTEST_LOCATION, locate_file ("cfg-test.rtl"));

  ASSERT_STREQ ("cfg_test", IDENTIFIER_POINTER (DECL_NAME (cfun->decl)));

  ASSERT_TRUE (cfun);

  ASSERT_TRUE (cfun->cfg != NULL);
  ASSERT_EQ (6, n_basic_blocks_for_fn (cfun));
  ASSERT_EQ (6, n_edges_for_fn (cfun));

  /* The "fake" basic blocks.  */
  basic_block entry = ENTRY_BLOCK_PTR_FOR_FN (cfun);
  ASSERT_TRUE (entry != NULL);
  ASSERT_EQ (ENTRY_BLOCK, entry->index);

  basic_block exit = EXIT_BLOCK_PTR_FOR_FN (cfun);
  ASSERT_TRUE (exit != NULL);
  ASSERT_EQ (EXIT_BLOCK, exit->index);

  /* The "real" basic blocks.  */
  basic_block bb2 = (*cfun->cfg->x_basic_block_info)[2];
  basic_block bb3 = (*cfun->cfg->x_basic_block_info)[3];
  basic_block bb4 = (*cfun->cfg->x_basic_block_info)[4];
  basic_block bb5 = (*cfun->cfg->x_basic_block_info)[5];

  ASSERT_EQ (2, bb2->index);
  ASSERT_EQ (3, bb3->index);
  ASSERT_EQ (4, bb4->index);
  ASSERT_EQ (5, bb5->index);

  /* Verify connectivity.  */

  /* Entry block.  */
  ASSERT_EQ (NULL, entry->preds);
  ASSERT_EQ (1, entry->succs->length ());
  ASSERT_EDGE ((*entry->succs)[0], 0, 2, EDGE_FALLTHRU);

  /* bb2.  */
  ASSERT_EQ (1, bb2->preds->length ());
  ASSERT_EDGE ((*bb2->preds)[0], 0, 2, EDGE_FALLTHRU);
  ASSERT_EQ (2, bb2->succs->length ());
  ASSERT_EDGE ((*bb2->succs)[0], 2, 3, EDGE_TRUE_VALUE);
  ASSERT_EDGE ((*bb2->succs)[1], 2, 4, EDGE_FALSE_VALUE);

  /* bb3.  */
  ASSERT_EQ (1, bb3->preds->length ());
  ASSERT_EDGE ((*bb3->preds)[0], 2, 3, EDGE_TRUE_VALUE);
  ASSERT_EQ (1, bb3->succs->length ());
  ASSERT_EDGE ((*bb3->succs)[0], 3, 5, EDGE_FALLTHRU);

  /* bb4.  */
  ASSERT_EQ (1, bb4->preds->length ());
  ASSERT_EDGE ((*bb4->preds)[0], 2, 4, EDGE_FALSE_VALUE);
  ASSERT_EQ (1, bb4->succs->length ());
  ASSERT_EDGE ((*bb4->succs)[0], 4, 5, EDGE_FALLTHRU);

  /* bb5.  */
  ASSERT_EQ (2, bb5->preds->length ());
  ASSERT_EDGE ((*bb5->preds)[0], 3, 5, EDGE_FALLTHRU);
  ASSERT_EDGE ((*bb5->preds)[1], 4, 5, EDGE_FALLTHRU);
  ASSERT_EQ (1, bb5->succs->length ());
  ASSERT_EDGE ((*bb5->succs)[0], 5, 1, EDGE_FALLTHRU);

  /* Exit block.  */
  ASSERT_EQ (1, exit->preds->length ());
  ASSERT_EDGE ((*exit->preds)[0], 5, 1, EDGE_FALLTHRU);
  ASSERT_EQ (NULL, exit->succs);
}

/* Verify that the loader copes with sparse block indices.
   This testcase loads a file with a "(block 42)".  */

static void
test_loading_bb_index ()
{
  rtl_dump_test t (SELFTEST_LOCATION, locate_file ("bb-index.rtl"));

  ASSERT_STREQ ("test_bb_index", IDENTIFIER_POINTER (DECL_NAME (cfun->decl)));

  ASSERT_TRUE (cfun);

  ASSERT_TRUE (cfun->cfg != NULL);
  ASSERT_EQ (3, n_basic_blocks_for_fn (cfun));
  ASSERT_EQ (43, basic_block_info_for_fn (cfun)->length ());
  ASSERT_EQ (2, n_edges_for_fn (cfun));

  ASSERT_EQ (NULL, (*cfun->cfg->x_basic_block_info)[41]);
  basic_block bb42 = (*cfun->cfg->x_basic_block_info)[42];
  ASSERT_NE (NULL, bb42);
  ASSERT_EQ (42, bb42->index);
}

/* Verify that function_reader::handle_any_trailing_information correctly
   parses all the possible items emitted for a MEM.  */

static void
test_loading_mem ()
{
  rtl_dump_test t (SELFTEST_LOCATION, locate_file ("mem.rtl"));

  ASSERT_STREQ ("test_mem", IDENTIFIER_POINTER (DECL_NAME (cfun->decl)));
  ASSERT_TRUE (cfun);

  /* Verify parsing of "[42 i+17 S8 A128 AS5]".  */
  rtx_insn *insn_1 = get_insn_by_uid (1);
  rtx set1 = single_set (insn_1);
  rtx mem1 = SET_DEST (set1);
  ASSERT_EQ (42, MEM_ALIAS_SET (mem1));
  /* "+17".  */
  ASSERT_TRUE (MEM_OFFSET_KNOWN_P (mem1));
  ASSERT_KNOWN_EQ (17, MEM_OFFSET (mem1));
  /* "S8".  */
  ASSERT_KNOWN_EQ (8, MEM_SIZE (mem1));
  /* "A128.  */
  ASSERT_EQ (128, MEM_ALIGN (mem1));
  /* "AS5.  */
  ASSERT_EQ (5, MEM_ADDR_SPACE (mem1));

  /* Verify parsing of "43 i+18 S9 AS6"
     (an address space without an alignment).  */
  rtx_insn *insn_2 = get_insn_by_uid (2);
  rtx set2 = single_set (insn_2);
  rtx mem2 = SET_DEST (set2);
  ASSERT_EQ (43, MEM_ALIAS_SET (mem2));
  /* "+18".  */
  ASSERT_TRUE (MEM_OFFSET_KNOWN_P (mem2));
  ASSERT_KNOWN_EQ (18, MEM_OFFSET (mem2));
  /* "S9".  */
  ASSERT_KNOWN_EQ (9, MEM_SIZE (mem2));
  /* "AS6.  */
  ASSERT_EQ (6, MEM_ADDR_SPACE (mem2));
}

/* Verify that "repeated xN" is read correctly.  */

static void
test_loading_repeat ()
{
  rtl_dump_test t (SELFTEST_LOCATION, locate_file ("repeat.rtl"));

  rtx_insn *insn_1 = get_insn_by_uid (1);
  ASSERT_EQ (PARALLEL, GET_CODE (PATTERN (insn_1)));
  ASSERT_EQ (64, XVECLEN (PATTERN (insn_1), 0));
  for (int i = 0; i < 64; i++)
    ASSERT_EQ (const0_rtx, XVECEXP (PATTERN (insn_1), 0, i));
}

/* Run all of the selftests within this file.  */

void
read_rtl_function_c_tests ()
{
  test_edge_flags ();
  test_parsing_regnos ();
  test_loading_dump_fragment_1 ();
  test_loading_dump_fragment_2 ();
  test_loading_labels ();
  test_loading_insn_with_mode ();
  test_loading_jump_to_label_ref ();
  test_loading_jump_to_return ();
  test_loading_jump_to_simple_return ();
  test_loading_note_insn_basic_block ();
  test_loading_note_insn_deleted ();
  test_loading_const_int ();
  test_loading_symbol_ref ();
  test_loading_cfg ();
  test_loading_bb_index ();
  test_loading_mem ();
  test_loading_repeat ();
}

} // namespace selftest

#endif /* #if CHECKING_P */
