From eab204018b559792b791fcd30fe48fd4632906ff Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Wed, 19 Oct 2016 15:47:32 -0400
Subject: [PATCH 17/20] FIXME: function_reader fixups

---
 gcc/read-rtl-function.c                           | 163 +++++++++-------------
 gcc/testsuite/selftests/example-labels.rtl        |   4 +-
 gcc/testsuite/selftests/jump-to-label-ref.rtl     |   7 +-
 gcc/testsuite/selftests/jump-to-return.rtl        |  13 +-
 gcc/testsuite/selftests/jump-to-simple-return.rtl |  14 +-
 5 files changed, 76 insertions(+), 125 deletions(-)

diff --git a/gcc/read-rtl-function.c b/gcc/read-rtl-function.c
index 3e7adb7..d882af3 100644
--- a/gcc/read-rtl-function.c
+++ b/gcc/read-rtl-function.c
@@ -129,16 +129,13 @@ class function_reader : public rtx_reader
 				  int operand_idx,
 				  const char *filename, int lineno);
 
-  void add_fixup_jump_label (file_location loc, rtx insn,
-			     int operand_idx,
-			     const char *label);
-
   void add_fixup_expr (file_location loc, rtx x,
 		       const char *desc);
 
   rtx consolidate_singletons (rtx x);
   void maybe_read_location (int operand_idx, rtx insn);
 
+  void assign_insn_uids ();
   void apply_fixups ();
 
  private:
@@ -239,27 +236,6 @@ class fixup_note_insn_basic_block : public operand_fixup
   int m_bb_idx;
 };
 
-/* A concrete subclass of operand_fixup: fix up the JUMP_LABEL
-   of an insn based on a label name.  */
-
-class fixup_jump_label : public operand_fixup
-{
- public:
-  fixup_jump_label (file_location loc, rtx insn,
-		    int operand_idx,
-		    const char *label)
-    : operand_fixup (loc, insn, operand_idx),
-      m_label (xstrdup (label))
-  {}
-
-  ~fixup_jump_label () { free (m_label); }
-
-  void apply (function_reader *reader) const;
-
- private:
-  char *m_label;
-};
-
 /* A concrete subclass of fixup (not operand_fixup): fix up
    the expr of an rtx (REG or MEM) based on a textual dump.  */
 
@@ -346,28 +322,6 @@ fixup_note_insn_basic_block::apply (function_reader */*reader*/) const
   NOTE_BASIC_BLOCK (m_rtx) = bb;
 }
 
-/* Fix up the JUMP_LABEL of an insn based on a label name.  */
-
-void
-fixup_jump_label::apply (function_reader *reader) const
-{
-  if (0 == strcmp (m_label, "return"))
-    JUMP_LABEL (m_rtx) = ret_rtx;
-  else if (0 == strcmp (m_label, "simple_return"))
-    JUMP_LABEL (m_rtx) = simple_return_rtx;
-  else
-    {
-      int label_uid = atoi (m_label);
-      rtx_insn **insn_from_uid = reader->get_insn_by_uid (label_uid);
-      if (insn_from_uid)
-	JUMP_LABEL (m_rtx) = *insn_from_uid;
-      else
-	error_at (m_loc,
-		  "insn with UID %i not found for operand %i (`%s') of insn %i",
-		  label_uid, m_operand_idx, "JUMP_LABEL", INSN_UID (m_rtx));
-    }
-}
-
 /* Fix up the expr of an rtx (REG or MEM) based on a textual dump.  */
 
 void
@@ -541,8 +495,18 @@ function_reader::parse_function ()
 	fatal_with_file_and_line ("missing 'crtl'");
     }
 
+  assign_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 ());
+
+
   /* 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.  */
   {
@@ -551,7 +515,6 @@ function_reader::parse_function ()
     for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
       max_uid = MAX (max_uid, INSN_UID (insn));
     crtl->emit.x_cur_insn_uid = max_uid + 1;
-    // FIXME: all of this may no longer be necessary
   }
 
   crtl->init_stack_alignment ();
@@ -876,15 +839,11 @@ function_reader::parse_insn (file_location start_loc, const char *name)
       set_first_insn (insn);
     }
 
-  /* Set a UID for "insn" and record it.  */
-  INSN_UID (insn) = crtl->emit.x_cur_insn_uid++;
-  m_insns_by_uid.put (INSN_UID (insn), insn);
-
   return insn;
 }
 
-/* Subroutine for parse_insn_chain: all the basic blocks should
-   have been created by now; create the edges that were seen.  */
+/* 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 ()
@@ -1225,18 +1184,6 @@ function_reader::extra_parsing_for_operand_code_0 (rtx return_rtx, int idx)
       else
 	unread_char (c);
     }
-  else if (idx == 7 && JUMP_P (return_rtx))
-    {
-      c = read_skip_spaces ();
-      if (c != '-')
-	{
-	  unread_char (c);
-	  return return_rtx;
-	}
-      require_char ('>');
-      file_location loc = read_name (&name);
-      add_fixup_jump_label (loc, return_rtx, idx, name.string);
-    }
 
   return return_rtx;
 }
@@ -1425,16 +1372,6 @@ function_reader::add_fixup_source_location (file_location, rtx,
 /* Record the information for later post-processing.  */
 
 void
-function_reader::add_fixup_jump_label (file_location loc, rtx insn,
-				       int operand_idx,
-				       const char *label)
-{
-  m_fixups.safe_push (new fixup_jump_label (loc, insn, operand_idx, label));
-}
-
-/* Record the information for later post-processing.  */
-
-void
 function_reader::add_fixup_expr (file_location loc, rtx insn,
 				 const char *desc)
 {
@@ -1445,15 +1382,6 @@ function_reader::add_fixup_expr (file_location loc, rtx insn,
   m_fixups.safe_push (new fixup_expr (loc, insn, desc));
 }
 
-/* Record the information for later post-processing.  */
-#if 0
-void
-function_reader::add_fixup_pseudo (file_location loc, rtx x)
-{
-  m_fixups.safe_push (new fixup_pseudo (loc, x));
-}
-#endif
-
 /* Helper function for consolidate_reg.  */
 
 static rtx
@@ -1627,6 +1555,44 @@ function_reader::maybe_read_location (int operand_idx, rtx insn)
 			     filename, atoi(name.string));
 }
 
+/* Postprocessing subroutine of function_reader::parse_function.
+   At this point, only CODE_LABELs have INSN_UID values (based
+   on the values seen in the dump).
+   Give everything else an INSN_UID, ensuring no duplication,
+   preserving the values in CODE_LABELs, and setting up
+   crtl->emit.x_cur_insn_uid.  */
+
+void
+function_reader::assign_insn_uids ()
+{
+  /* Locate the currently assigned INSN_UID values, storing
+     them in m_insns_by_uid.  */
+  for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
+    if (INSN_UID (insn))
+      {
+	gcc_assert (GET_CODE (insn) == CODE_LABEL);
+
+	m_insns_by_uid.put (INSN_UID (insn), insn);
+      }
+
+  /* Give everything else an INSN_UID.  */
+  for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
+    {
+      if (!INSN_UID (insn))
+	{
+	  /* Generate a non-duplicate INSN_UID value.  */
+	  int uid;
+	  do
+	    uid = crtl->emit.x_cur_insn_uid++;
+	  while (m_insns_by_uid.get (uid));
+
+	  /* Set the UID for "insn" and record it.  */
+	  INSN_UID (insn) = uid;
+	  m_insns_by_uid.put (uid, insn);
+	}
+    }
+}
+
 /* Apply all of the recorded fixups.  */
 
 void
@@ -1895,21 +1861,23 @@ test_loading_labels ()
 {
   rtl_dump_test t (SELFTEST_LOCATION, locate_file ("example-labels.rtl"));
 
-  rtx_insn *insn_1 = get_insn_by_uid (1);
-  ASSERT_EQ (CODE_LABEL, GET_CODE (insn_1));
-  ASSERT_EQ (NULL, LABEL_NAME (insn_1));
-  ASSERT_EQ (0, LABEL_NUSES (insn_1));
+  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));
 
-  rtx_insn *insn_2 = get_insn_by_uid (2);
-  ASSERT_EQ (CODE_LABEL, GET_CODE (insn_2));
-  ASSERT_STREQ ("some_label_name", LABEL_NAME (insn_2));
-  ASSERT_EQ (0, LABEL_NUSES (insn_2));
+  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));
 
   /* 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_2));
-  ASSERT_TRUE (ggc_marked_p (LABEL_NAME (insn_2)));
+  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.  */
@@ -1938,7 +1906,7 @@ test_loading_jump_to_label_ref ()
   rtx_insn *barrier = get_insn_by_uid (2);
   ASSERT_EQ (BARRIER, GET_CODE (barrier));
 
-  rtx_insn *code_label = get_insn_by_uid (3);
+  rtx_insn *code_label = get_insn_by_uid (100);
   ASSERT_EQ (CODE_LABEL, GET_CODE (code_label));
 
   /* Verify the jump_insn. */
@@ -1955,8 +1923,7 @@ test_loading_jump_to_label_ref ()
   /* Verify the code_label. */
   ASSERT_EQ (5, BLOCK_FOR_INSN (code_label)->index);
   ASSERT_EQ (NULL, LABEL_NAME (code_label));
-  // FIXME:
-  //ASSERT_EQ (1, LABEL_NUSES (code_label));
+  ASSERT_EQ (1, LABEL_NUSES (code_label));
 
   /* Verify the generated CFG.  */
 
diff --git a/gcc/testsuite/selftests/example-labels.rtl b/gcc/testsuite/selftests/example-labels.rtl
index d147e12..c4cd9b2 100644
--- a/gcc/testsuite/selftests/example-labels.rtl
+++ b/gcc/testsuite/selftests/example-labels.rtl
@@ -1,8 +1,8 @@
 (function "example_labels"
   (insn-chain
     (block 6
-      (clabel 1 3 (nil))
-      (clabel 2 3 ("some_label_name"))
+      (clabel 100 3 (nil))
+      (clabel 200 3 ("some_label_name"))
     ) ;; block 6
   ) ;; insn-chain
 ) ;; function
diff --git a/gcc/testsuite/selftests/jump-to-label-ref.rtl b/gcc/testsuite/selftests/jump-to-label-ref.rtl
index a07fe41..80efa05 100644
--- a/gcc/testsuite/selftests/jump-to-label-ref.rtl
+++ b/gcc/testsuite/selftests/jump-to-label-ref.rtl
@@ -2,16 +2,15 @@
   (insn-chain
     (block 4
       (edge-from entry (flags "FALLTHRU"))
-      (cjump_insn (set (pc) (label_ref 3))
+      (cjump_insn (set (pc) (label_ref 100))
         "../../src/gcc/testsuite/rtl.dg/test.c":4
-        (nil)
-        -> 3)
+        (nil))
       (edge-to 5)
     ) ;; block 4
     (cbarrier)
     (block 5   
       (edge-from 4)
-      (clabel 3 2 (nil) [1 uses])
+      (clabel 100 2 (nil) [1 uses])
       (edge-to exit (flags "FALLTHRU"))
     ) ;; block 5
   ) ;; insn-chain
diff --git a/gcc/testsuite/selftests/jump-to-return.rtl b/gcc/testsuite/selftests/jump-to-return.rtl
index 79bd4dc..3652fea 100644
--- a/gcc/testsuite/selftests/jump-to-return.rtl
+++ b/gcc/testsuite/selftests/jump-to-return.rtl
@@ -2,17 +2,10 @@
   (insn-chain
     (block 4
       (edge-from entry (flags "FALLTHRU"))
-      (cjump_insn (set (pc) (clabel_ref 3))
+      (cjump_insn (return)
         "../../src/gcc/testsuite/rtl.dg/test.c":4
-        (nil)
-        -> return)
-      (edge-to 5)
-    ) ;; block 4
-    (cbarrier)
-    (block 5   
-      (edge-from 4)
-      (clabel 3 2 (nil) [1 uses])
+        (nil))
       (edge-to exit (flags "FALLTHRU"))
-    ) ;; block 5
+    ) ;; block 4
   ) ;; insn-chain
 ) ;; function
diff --git a/gcc/testsuite/selftests/jump-to-simple-return.rtl b/gcc/testsuite/selftests/jump-to-simple-return.rtl
index fae0645..f8d0cc8 100644
--- a/gcc/testsuite/selftests/jump-to-simple-return.rtl
+++ b/gcc/testsuite/selftests/jump-to-simple-return.rtl
@@ -2,18 +2,10 @@
   (insn-chain
     (block 4
       (edge-from entry (flags "FALLTHRU"))
-      (cjump_insn (set (pc) (label_ref 3))
+      (cjump_insn (simple_return)
         "../../src/gcc/testsuite/rtl.dg/test.c":4
-        (nil)
-        -> simple_return)
-      (edge-to 5)
-    ) ;; block 4
-    (cbarrier)
-    (block 5   
-      (edge-from 4)
-      (clabel 3 2 (nil) [1 uses])
+        (nil))
       (edge-to exit (flags "FALLTHRU"))
-    ) ;; block 5
+    ) ;; block 4
   ) ;; insn-chain
 ) ;; function
-
-- 
1.8.5.3

