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

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

struct deferred_edge
{
  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);

  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: '%s'", 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: '%s'", 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)
{
}

/* 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);
      add_fixup_source_location (loc, insn, filename, atoi (line_num.string));
    }
  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 ();
  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 ();
  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 */
