Hi,
Based on previous patch, this one implements live range, reg pressure 
computation
class in tree-ssa-live.c.  The user would only need to instantiate the class and
call the computation interface as in next patch.
During the work, I think it's also worthwhile to classify all live range and 
coalesce
data structures and algorithms in the future.

Bootstrap and test on x86_64 and AArch64 ongoing.  Any comments?

Thanks,
bin
2018-04-27  Bin Cheng  <bin.ch...@arm.com>

        * tree-ssa-live.c (memmodel.h, ira.h, tree-ssa-coalesce.h): Include.
        (struct stmt_lr_info, free_stmt_lr_info): New.
        (lr_region::lr_region, lr_region::~lr_region): New.
        (lr_region::create_stmt_lr_info): New.
        (lr_region::update_live_range_by_stmt): New.
        (lr_region::calculate_coalesced_pressure): New.
        (lr_region::calculate_pressure): New.
        * tree-ssa-live.h (struct stmt_lr_info): New declaration.
        (class lr_region): New class.
From 5c16db5672a4f0826d2a164823759a9ffb12c349 Mon Sep 17 00:00:00 2001
From: Bin Cheng <binch...@e108451-lin.cambridge.arm.com>
Date: Fri, 4 May 2018 09:42:04 +0100
Subject: [PATCH 5/6] region-reg-pressure-20180428

---
 gcc/tree-ssa-live.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 gcc/tree-ssa-live.h |  49 ++++++++++++++++
 2 files changed, 206 insertions(+)

diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
index ccb0d99..e51cd15 100644
--- a/gcc/tree-ssa-live.c
+++ b/gcc/tree-ssa-live.c
@@ -23,6 +23,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "backend.h"
 #include "rtl.h"
+#include "memmodel.h"
+#include "ira.h"
 #include "tree.h"
 #include "gimple.h"
 #include "timevar.h"
@@ -34,6 +36,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-dfa.h"
 #include "dumpfile.h"
 #include "tree-ssa-live.h"
+#include "tree-ssa-coalesce.h"
 #include "debug.h"
 #include "tree-ssa.h"
 #include "ipa-utils.h"
@@ -1204,6 +1207,160 @@ calculate_live_ranges (var_map map, bool want_livein)
 }
 
 
+/* Live range information for a gimple stmt.  */
+struct stmt_lr_info
+{
+  /*  ID of the stmt.  */
+  unsigned id;
+  gimple *stmt;
+  /* Live ranges after the stmt.  */
+  bitmap lr_after_stmt;
+};
+
+/* Call back function to free live range INFO of gimple STMT.  */
+
+bool
+free_stmt_lr_info (gimple *const & stmt, stmt_lr_info *const &info, void *)
+{
+  gcc_assert (info->stmt == stmt);
+  if (info->lr_after_stmt != NULL)
+    BITMAP_FREE (info->lr_after_stmt);
+
+  free (info);
+  return true;
+}
+
+lr_region::lr_region (struct loop *loop)
+  : m_loop (loop),
+    m_varmap (NULL),
+    m_liveinfo (NULL),
+    m_stmtmap (new hash_map<gimple *, stmt_lr_info *> (13))
+{
+  memset (m_pressure, 0, sizeof (unsigned) * N_REG_CLASSES);
+}
+
+lr_region::~lr_region ()
+{
+  m_stmtmap->traverse<void *, free_stmt_lr_info> (NULL);
+  delete m_stmtmap;
+}
+
+struct stmt_lr_info *
+lr_region::create_stmt_lr_info (gimple *stmt)
+{
+  bool exist_p;
+  struct stmt_lr_info **slot = &m_stmtmap->get_or_insert (stmt, &exist_p);
+
+  gcc_assert (!exist_p);
+  *slot = XCNEW (struct stmt_lr_info);
+  (*slot)->stmt = stmt;
+  (*slot)->lr_after_stmt = NULL;
+  return *slot;
+}
+
+void
+lr_region::update_live_range_by_stmt (gimple *stmt, bitmap live_ranges,
+				      unsigned *pressure)
+{
+  int p;
+  tree var;
+  ssa_op_iter iter;
+
+  FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_DEF)
+    {
+      p = var_to_partition (m_varmap, var);
+      gcc_assert (p != NO_PARTITION);
+      if (bitmap_clear_bit (live_ranges, p))
+	pressure[ira_mode_classes[TYPE_MODE (TREE_TYPE (var))]]--;
+    }
+  FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
+    {
+      p = var_to_partition (m_varmap, var);
+      gcc_assert (p != NO_PARTITION);
+      if (bitmap_set_bit (live_ranges, p))
+	pressure[ira_mode_classes[TYPE_MODE (TREE_TYPE (var))]]++;
+    }
+}
+
+void
+lr_region::calculate_coalesced_pressure ()
+{
+  unsigned i, j, reg_class, pressure[N_REG_CLASSES];
+  bitmap_iterator bi, bj;
+  gimple_stmt_iterator bsi;
+  auto_bitmap live_ranges;
+  bitmap bbs = get_bbs ();
+
+  EXECUTE_IF_SET_IN_BITMAP (bbs, 0, i, bi)
+    {
+      basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i);
+      bitmap_copy (live_ranges, &m_liveinfo->liveout[bb->index]);
+
+      memset (pressure, 0, sizeof (unsigned) * N_REG_CLASSES);
+      EXECUTE_IF_SET_IN_BITMAP (live_ranges, 0, j, bj)
+	{
+	  tree var = partition_to_var (m_varmap, j);
+	  reg_class = ira_mode_classes[TYPE_MODE (TREE_TYPE (var))];
+	  pressure[reg_class]++;
+	}
+
+      for (bsi = gsi_last_bb (bb); !gsi_end_p (bsi); gsi_prev (&bsi))
+	{
+	  gimple *stmt = gsi_stmt (bsi);
+	  struct stmt_lr_info *stmt_info = create_stmt_lr_info (stmt);
+	  /* No need to compute live range information for debug stmt.  */
+	  if (is_gimple_debug (stmt))
+	    continue;
+
+	  for (j = 0; j < N_REG_CLASSES; j++)
+	    if (pressure[j] > m_pressure[j])
+	      m_pressure[j] = pressure[j];
+
+	  stmt_info->lr_after_stmt = BITMAP_ALLOC (NULL);
+	  bitmap_copy (stmt_info->lr_after_stmt, live_ranges);
+	  update_live_range_by_stmt (stmt, live_ranges, pressure);
+	}
+    }
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    {
+      fprintf (dump_file, "Max Reg Pressure:\n");
+      for (i = 0; i < N_REG_CLASSES; ++i)
+	if (m_pressure[i] != 0)
+	  fprintf (dump_file, "    %s: \t%d\n",
+		   reg_class_names[i], m_pressure[i]);
+    }
+}
+
+bool
+lr_region::calculate_pressure (unsigned *max_pressure)
+{
+  /* Coalesce SSA variables.  */
+  m_varmap = coalesce_ssa_name (m_loop, true);
+  partition_view_normal (m_varmap);
+
+  /* Calculate live ranges for region based on coalesced variables.  */
+  m_liveinfo = calculate_live_ranges (m_varmap, true);
+
+  /* Calculate register pressure.  */
+  calculate_coalesced_pressure ();
+
+  bool high_pressure_p = false;
+  for (unsigned k = 0; k < N_REG_CLASSES; k++)
+    {
+      if (m_pressure[k] >= pressure_threshold ()
+	  && m_pressure[k] > target_avail_regs[k])
+	high_pressure_p = true;
+
+      max_pressure[k] = m_pressure[k];
+    }
+
+  delete_tree_live_info (m_liveinfo);
+  delete_var_map (m_varmap);
+
+  return high_pressure_p;
+}
+
+
 /* Output partition map MAP to file F.  */
 
 void
diff --git a/gcc/tree-ssa-live.h b/gcc/tree-ssa-live.h
index fa6f68d..f8fdd0a 100644
--- a/gcc/tree-ssa-live.h
+++ b/gcc/tree-ssa-live.h
@@ -347,4 +347,53 @@ make_live_on_entry (tree_live_info_p live, basic_block bb , int p)
   bitmap_set_bit (live->global, p);
 }
 
+struct stmt_lr_info;
+
+/* Live range region class.  Only loop region is supported for now.  */
+class lr_region
+{
+public:
+  lr_region (struct loop *loop);
+  ~lr_region ();
+
+  /* Threshold for register pressure above which is considered as high.  */
+  unsigned pressure_threshold () const { return 16; }
+
+  /* Calculate maximum reg pressure information for region and store it in
+     MAX_PRESSURE.  Return true if the reg pressure is high.  */
+  bool calculate_pressure (unsigned *max_pressure);
+private:
+  lr_region (const lr_region&);
+  lr_region &operator= (const lr_region&);
+
+  /* Return bitmap of basic blocks in this region.  */
+  bitmap get_bbs () const { return m_varmap->bmp_bbs; }
+
+  /* Create and return live range information for STMT.  */
+  struct stmt_lr_info *create_stmt_lr_info (gimple *stmt);
+
+  /* Update LIVE_RANGES bitmap and register PRESSURE information by backward
+     executing STMT.  */
+  void update_live_range_by_stmt (gimple *stmt, bitmap live_range,
+				  unsigned *pressure);
+
+  /* Calculate reg pressure information for REGION.  */
+  void calculate_coalesced_pressure ();
+
+  /* The loop from which this region is formed.  */
+  struct loop* m_loop;
+
+  /* SSA variable map for coalescing and reg pressure computation.  */
+  var_map m_varmap;
+
+  /* Live range information of this region.  */
+  tree_live_info_p m_liveinfo;
+
+  /* Map from gimple stmt to its live range information.  */
+  hash_map<gimple *, stmt_lr_info *> *m_stmtmap;
+
+  /* Register pressure information.  */
+  unsigned m_pressure[N_REG_CLASSES];
+};
+
 #endif /* _TREE_SSA_LIVE_H  */
-- 
1.9.1

Reply via email to