diff mbox series

[RFC/RFA,v5,11/12] Replace the original CRC loops with a faster CRC calculation.

Message ID CAE65F3MKRnS1B7ZVYhVhZhMwavd7ytzD_87bd2G+j=_W5xABQw@mail.gmail.com
State New
Headers show
Series CRC optimization. | expand

Commit Message

Mariam Arutunian Oct. 18, 2024, 3:01 p.m. UTC
After the loop exit an internal function call (CRC, CRC_REV) is added,
and its result is assigned to the output CRC variable (the variable where
the calculated CRC is stored
after the loop execution).
The removal of the loop is left to CFG cleanup and DCE.

  gcc/

    * gimple-crc-optimization.cc (optimize_crc_loop): New function.
    (execute): Add optimize_crc_loop function call.

Signed-off-by: Mariam Arutunian <mariamarutunian@gmail.com>
Mentored-by: Jeff Law <jlaw@ventanamicro.com>
diff mbox series

Patch

---
 gcc/gimple-crc-optimization.cc | 78 ++++++++++++++++++++++++++++++++++
 1 file changed, 78 insertions(+)

diff --git a/gcc/gimple-crc-optimization.cc b/gcc/gimple-crc-optimization.cc
index a05aaf9f217..9dee9be85d0 100644
--- a/gcc/gimple-crc-optimization.cc
+++ b/gcc/gimple-crc-optimization.cc
@@ -225,6 +225,11 @@  class crc_optimization {
   /* Returns phi statement which may hold the calculated CRC.  */
   gphi *get_output_phi ();
 
+  /* Attempts to optimize a CRC calculation loop by replacing it with a call to
+     an internal function (IFN_CRC or IFN_CRC_REV).
+     Returns true if replacement is succeeded, otherwise false.  */
+  bool optimize_crc_loop (gphi *output_crc);
+
  public:
   crc_optimization () : m_visited_stmts (BITMAP_ALLOC (NULL)),
 			m_crc_loop (nullptr), m_polynomial (0)
@@ -1215,6 +1220,73 @@  crc_optimization::get_output_phi ()
   return nullptr;
 }
 
+/* Attempts to optimize a CRC calculation loop by replacing it with a call to
+   an internal function (IFN_CRC or IFN_CRC_REV).
+   Returns true if replacement is succeeded, otherwise false.  */
+
+bool
+crc_optimization::optimize_crc_loop (gphi *output_crc)
+{
+  if (!output_crc)
+    {
+      if (dump_file)
+	fprintf (dump_file, "Couldn't determine output CRC.\n");
+      return false;
+    }
+
+  if (!m_data_arg)
+    {
+      if (dump_file && (dump_flags & TDF_DETAILS))
+	fprintf (dump_file,
+		 "Data and CRC are xor-ed before for loop.  Initializing data "
+		 "with 0.\n");
+      /* Create a new variable for the data.
+       Determine the data's size with the loop iteration count.  */
+      unsigned HOST_WIDE_INT
+	data_size = tree_to_uhwi (m_crc_loop->nb_iterations) + 1;
+      tree type = build_nonstandard_integer_type (data_size, 1);
+     /* For the CRC calculation, it doesn't matter CRC is calculated for the
+	(CRC^data, 0) or (CRC, data).  */
+      m_data_arg = build_int_cstu (type, 0);
+    }
+
+  /* Build tree node for the polynomial from its constant value.  */
+  tree polynomial_arg = build_int_cstu (TREE_TYPE (m_crc_arg), m_polynomial);
+  gcc_assert (polynomial_arg);
+
+  internal_fn ifn;
+  if (m_is_bit_forward)
+    ifn = IFN_CRC;
+  else
+    ifn = IFN_CRC_REV;
+
+  tree phi_result = gimple_phi_result (output_crc);
+  location_t loc;
+  loc = EXPR_LOCATION (phi_result);
+
+  /* Add IFN call and write the return value in the phi_result.  */
+  gcall *call
+      = gimple_build_call_internal (ifn, 3,
+				    m_crc_arg,
+				    m_data_arg,
+				    polynomial_arg);
+
+  gimple_call_set_lhs (call, phi_result);
+  gimple_set_location (call, loc);
+  gimple_stmt_iterator si = gsi_start_bb (output_crc->bb);
+  gsi_insert_before (&si, call, GSI_SAME_STMT);
+
+  /* Remove phi statement, which was holding CRC result.  */
+  gimple_stmt_iterator tmp_gsi = gsi_for_stmt (output_crc);
+  remove_phi_node (&tmp_gsi, false);
+
+  /* Alter the exit condition of the loop to always exit.  */
+  gcond* loop_exit_cond = get_loop_exit_condition (m_crc_loop);
+  gimple_cond_make_false (loop_exit_cond);
+  update_stmt (loop_exit_cond);
+  return true;
+}
+
 unsigned int
 crc_optimization::execute (function *fun)
 {
@@ -1271,6 +1343,12 @@  crc_optimization::execute (function *fun)
 	  if (dump_file)
 	    fprintf (dump_file, "The loop with %d header BB index "
 				"calculates CRC!\n", m_crc_loop->header->index);
+
+	  if (!optimize_crc_loop (output_crc))
+	    {
+	      if (dump_file)
+		fprintf (dump_file, "Couldn't generate faster CRC code.\n");
+	    }
 	}
     }
   return 0;
-- 
2.25.1