From 7a4218466aaa378cd301092a1c77aefa8fc3ada9 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 7 Apr 2016 16:33:29 -0400
Subject: [PATCH 37/55] FIXME: create function and cfg; reconstruct XBBDEF
 within each insn

---
 gcc/read-md.h          |   4 ++
 gcc/read-rtl.c         |  10 +++-
 gcc/rtl/rtl-frontend.c | 154 ++++++++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 157 insertions(+), 11 deletions(-)

diff --git a/gcc/read-md.h b/gcc/read-md.h
index 34e3313..6a7a551 100644
--- a/gcc/read-md.h
+++ b/gcc/read-md.h
@@ -100,6 +100,10 @@ class rtx_reader
 				   int /*operand_idx*/, int /*insn_uid*/)
   {}
 
+  virtual void add_fixup_bb (file_location /*loc*/, rtx /*insn*/,
+			     int /*operand_idx*/, int /*bb_idx*/)
+  {}
+
   file_location get_current_location () const;
 
   void update_location (bool advancing);
diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c
index b4a9664..04e602c 100644
--- a/gcc/read-rtl.c
+++ b/gcc/read-rtl.c
@@ -1598,9 +1598,13 @@ read_rtx_code (const char *code_name)
 
       case 'B':
 	{
-	  read_name_or_nil (&name);
-	  fprintf (stderr, "FIXME: do something with basic block ID: '%s'\n",
-		   name.string);
+	  file_location loc = read_name_or_nil (&name);
+#ifndef GENERATOR_FILE
+	  inform (loc, "FIXME: do something with basic block ID: %qs",
+		  name.string);
+#endif
+	  int bb_idx = atoi (name.string);
+	  rtx_reader_ptr->add_fixup_bb (loc, return_rtx, i, bb_idx);
 	}
 	break;
 
diff --git a/gcc/rtl/rtl-frontend.c b/gcc/rtl/rtl-frontend.c
index 7b2ec01..7a1b26b 100644
--- a/gcc/rtl/rtl-frontend.c
+++ b/gcc/rtl/rtl-frontend.c
@@ -36,6 +36,13 @@ along with GCC; see the file COPYING3.  If not see
 #include "read-md.h"
 #include <mpfr.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"
 
 /* Language-dependent contents of a type.  */
 
@@ -161,30 +168,64 @@ class function_reader;
 class fixup
 {
  public:
-  fixup (file_location loc, rtx insn, int operand_idx, int insn_uid)
-    : m_loc (loc), m_insn (insn), m_operand_idx (operand_idx),
-      m_insn_uid (insn_uid)
+  fixup (file_location loc, rtx insn, int operand_idx)
+    : m_loc (loc), m_insn (insn), m_operand_idx (operand_idx)
   {}
+  virtual ~fixup () {}
 
-  void apply (function_reader *reader) const;
+  virtual void apply (function_reader *reader) const = 0;
 
- private:
+ protected:
   file_location m_loc;
   rtx m_insn;
   int m_operand_idx;
+};
+
+class fixup_insn_uid : public fixup
+{
+ public:
+  fixup_insn_uid (file_location loc, rtx insn, int operand_idx, int insn_uid)
+    : fixup (loc, insn, operand_idx),
+      m_insn_uid (insn_uid)
+  {}
+
+  void apply (function_reader *reader) const;
+
+ private:
   int m_insn_uid;
 };
 
+class fixup_bb : public fixup
+{
+ public:
+  fixup_bb (file_location loc, rtx insn, int operand_idx, int bb_idx)
+    : fixup (loc, insn, operand_idx),
+      m_bb_idx (bb_idx)
+  {}
+
+  void apply (function_reader *reader) const;
+
+ private:
+  int m_bb_idx;
+};
+
 class function_reader : public rtx_reader
 {
  public:
-  function_reader (line_maps *set) : rtx_reader (set) {}
+  function_reader (line_maps *set) : rtx_reader (set), m_max_bb_idx (-1),
+    m_first_insn (NULL)
+  {}
+
   ~function_reader ();
   void handle_unknown_directive (file_location, const char *);
 
   void add_fixup_insn_uid (file_location loc, rtx insn, int operand_idx,
 			   int insn_uid);
 
+  void add_fixup_bb (file_location loc, rtx insn,
+		     int operand_idx, int bb_id);
+
+  void create_function ();
   void apply_fixups ();
 
   rtx *get_insn_by_uid (int uid);
@@ -193,6 +234,8 @@ class function_reader : public rtx_reader
   struct uid_hash : int_hash <int, -1, -2> {};
   hash_map<uid_hash, rtx> m_insns_by_uid;
   auto_vec<fixup *> m_fixups;
+  int m_max_bb_idx;
+  rtx_insn *m_first_insn;
 };
 
 static const char *
@@ -211,7 +254,7 @@ get_operand_name (rtx insn, int operand_idx)
 }
 
 void
-fixup::apply (function_reader *reader) const
+fixup_insn_uid::apply (function_reader *reader) const
 {
   rtx *insn_from_uid = reader->get_insn_by_uid (m_insn_uid);
   if (insn_from_uid)
@@ -230,6 +273,12 @@ fixup::apply (function_reader *reader) const
     }
 }
 
+void
+fixup_bb::apply (function_reader */*reader*/) const
+{
+  XBBDEF (m_insn, m_operand_idx) = BASIC_BLOCK_FOR_FN (cfun, m_bb_idx);
+}
+
 function_reader::~function_reader ()
 {
   int i;
@@ -245,6 +294,8 @@ function_reader::handle_unknown_directive (file_location start_loc,
   rtx x = read_rtx_code (name);
   if (!x)
     return;
+  if (!m_first_insn)
+    m_first_insn = as_a <rtx_insn *> (x);
   int c = read_char ();
   location_t end_loc = get_current_location ();
   unread_char (c);
@@ -258,7 +309,93 @@ void
 function_reader::add_fixup_insn_uid (file_location loc, rtx insn, int operand_idx,
 				     int insn_uid)
 {
-  m_fixups.safe_push (new fixup (loc, insn, operand_idx, insn_uid));
+  m_fixups.safe_push (new fixup_insn_uid (loc, insn, operand_idx, insn_uid));
+}
+
+void
+function_reader::add_fixup_bb (file_location loc, rtx insn, int operand_idx,
+			       int bb_idx)
+{
+  if (m_max_bb_idx < bb_idx)
+    m_max_bb_idx = bb_idx;
+  m_fixups.safe_push (new fixup_bb (loc, insn, operand_idx, bb_idx));
+}
+
+void
+function_reader::create_function ()
+{
+#if 1
+  cfg_layout_rtl_register_cfg_hooks ();
+#else
+  rtl_register_cfg_hooks ();
+#endif
+
+  /* TODO: create cfun.  */
+  // how is the function created? step through how C frontend creates it
+  /* example was: "int test_1 (int i, int j, int k)" */
+  tree fn_name = get_identifier ("test_1"); /* FIXME.  */
+  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_stat (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.  */
+
+  //struct function *fn = ; // DECL_STRUCT_FUNCTION (node->decl);
+  //push_cfun (fn);
+
+  /* Create cfg.  */
+#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. */
+  size_t new_size = m_max_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);
+
+  basic_block after = ENTRY_BLOCK_PTR_FOR_FN (cfun);
+  gcc_assert (after);
+  while (n_basic_blocks_for_fn (cfun) < new_size)
+    {
+      basic_block bb = alloc_block ();
+      init_rtl_bb_info (bb);
+      bb->index = n_basic_blocks_for_fn (cfun)++;
+      bb->flags = BB_NEW | BB_RTL;
+      link_block (bb, after);
+      SET_BASIC_BLOCK_FOR_FN (cfun, bb->index, 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;
+#if 0
+  BB_HEAD (bb) = head;
+  BB_END (bb) = end;
+#endif
+    }
+
+
+  /* TODO: create edges.  */
+
+  //pop_cfun ();
 }
 
 void
@@ -287,6 +424,7 @@ rtl_langhook_parse_file (void)
   if (!reader.read_md_files (argv.length (), argv.address (), NULL))
     return;
 
+  reader.create_function ();
   reader.apply_fixups ();
 }
 
-- 
1.8.5.3

