/* 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 (startswith (desc, "orig:"))
	{
	  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 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.  */
  ggc_collect (GGC_COLLECT_FORCE);
  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 */
