From 927552e2e8a43aab9d803979c782a1542571220d Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 14 Apr 2016 13:29:07 -0400
Subject: [PATCH 087/117] FIXME: introduce function_reader::create_cfg

---
 gcc/rtl/rtl-frontend.c | 137 ++++++++++++++++++++++++++-----------------------
 1 file changed, 73 insertions(+), 64 deletions(-)

diff --git a/gcc/rtl/rtl-frontend.c b/gcc/rtl/rtl-frontend.c
index 6180f62..4f02168 100644
--- a/gcc/rtl/rtl-frontend.c
+++ b/gcc/rtl/rtl-frontend.c
@@ -349,6 +349,9 @@ class function_reader : public rtx_reader
   tree parse_mem_expr (const char *desc);
 
  private:
+  void create_cfg ();
+
+ private:
   struct uid_hash : int_hash <int, -1, -2> {};
   hash_map<uid_hash, rtx_insn *> m_insns_by_uid;
   auto_vec<fixup *> m_fixups;
@@ -603,70 +606,7 @@ function_reader::create_function ()
   //struct function *fn = ; // DECL_STRUCT_FUNCTION (node->decl);
   //push_cfun (fn);
 
-  /* Create bare-bones cfg.  This creates the entry and exit blocks.  */
-#if 1
-  init_empty_tree_cfg_for_function (cfun);
-#else
-  init_flow (cfun);
-#endif
-
-  /* Populate with basic blocks.
-
-     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.
-
-     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 make the assumption that the CFG has been compacted, and
-     so 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) skip over these "holes".  */
-
-  /* Ensure that the vector of basic_block pointers is big enough.  */
-  unsigned highest_bb_idx = bitmap_last_set_bit (&m_bb_indices);
-  size_t new_size = 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);
-
-  /* Populate the vector.  */
-  unsigned bb_idx;
-  bitmap_iterator bi;
-  basic_block after = ENTRY_BLOCK_PTR_FOR_FN (cfun);
-  gcc_assert (after);
-  EXECUTE_IF_SET_IN_BITMAP (&m_bb_indices, 0, bb_idx, bi)
-    {
-      /* The entry and exit blocks were already created above.  */
-      if (bb_idx == ENTRY_BLOCK || bb_idx == EXIT_BLOCK)
-	continue;
-      basic_block bb = alloc_block ();
-      init_rtl_bb_info (bb);
-      bb->index = bb_idx;
-      bb->flags = BB_NEW | BB_RTL;
-      link_block (bb, after);
-
-      n_basic_blocks_for_fn (cfun)++;
-      SET_BASIC_BLOCK_FOR_FN (cfun, bb_idx, bb);
-      //df_bb_refs_record (bb->index, false);
-      //update_bb_for_insn (bb);
-      BB_SET_PARTITION (bb, BB_UNPARTITIONED);
-
-      /* Tag the block so that we know it has been used when considering
-	 other basic block notes.  */
-      bb->aux = bb;
-
-      after = bb;
-    }
-
-
-  /* TODO: create edges.  */
-
+  create_cfg ();
   cfun->curr_properties = (PROP_cfg | PROP_rtl);
 
   //pop_cfun ();
@@ -725,6 +665,75 @@ function_reader::get_insn_by_uid (int uid)
   return m_insns_by_uid.get (uid);
 }
 
+/* Create cfun's CFG and populate with blocks (TODO: and edges), a helper
+   function for function_reader::create_function ().
+
+   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.
+
+   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 make the assumption that the CFG has been compacted, and
+   so 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".  */
+
+void
+function_reader::create_cfg ()
+{
+  /* Create bare-bones cfg.  This creates the entry and exit blocks.  */
+#if 1
+  init_empty_tree_cfg_for_function (cfun);
+#else
+  init_flow (cfun);
+#endif
+
+  /* Ensure that the vector of basic_block pointers is big enough.  */
+  unsigned highest_bb_idx = bitmap_last_set_bit (&m_bb_indices);
+  size_t new_size = 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);
+
+  /* Populate the vector.  */
+  unsigned bb_idx;
+  bitmap_iterator bi;
+  basic_block after = ENTRY_BLOCK_PTR_FOR_FN (cfun);
+  gcc_assert (after);
+  EXECUTE_IF_SET_IN_BITMAP (&m_bb_indices, 0, bb_idx, bi)
+    {
+      /* The entry and exit blocks were already created above.  */
+      if (bb_idx == ENTRY_BLOCK || bb_idx == EXIT_BLOCK)
+	continue;
+      basic_block bb = alloc_block ();
+      init_rtl_bb_info (bb);
+      bb->index = bb_idx;
+      bb->flags = BB_NEW | BB_RTL;
+      link_block (bb, after);
+
+      n_basic_blocks_for_fn (cfun)++;
+      SET_BASIC_BLOCK_FOR_FN (cfun, bb_idx, bb);
+      //df_bb_refs_record (bb->index, false);
+      //update_bb_for_insn (bb);
+      BB_SET_PARTITION (bb, BB_UNPARTITIONED);
+
+      /* Tag the block so that we know it has been used when considering
+	 other basic block notes.  */
+      bb->aux = bb;
+
+      after = bb;
+    }
+
+  /* TODO: create edges.  */
+
+}
+
 /*  Locate and run PASS_NAME on cfun.  */
 
 static void
-- 
1.8.5.3

