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

  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 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 if 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 */
