On Fri, May 4, 2018 at 5:24 PM, Bin Cheng <bin.ch...@arm.com> wrote:
> Hi,
> This patch restricts predcom pass using register pressure information.
> In case of high register pressure, we now prune additional chains as well
> as disable unrolling in predcom.  In generally, I think this patch set is
> useful.
>
> Bootstrap and test on x86_64 ongoing.  Any comments?
Simple update in line with changes in previous patch.

Thanks,
bin
>
> Thanks,
> bin
> 2018-04-27  Bin Cheng  <bin.ch...@arm.com>
>
>         * tree-predcom.c (stor-layout.h, tree-ssa-live.h): Include.
>         (REG_RELAX_RATIO, prune_chains): New.
>         (tree_predictive_commoning_loop): Compute reg pressure using class
>         region.  Prune chains based on reg pressure.  Force to not unroll
>         if reg pressure is high.
From b78c779907b98930fc4b36e5558d6f315bb4475b Mon Sep 17 00:00:00 2001
From: Bin Cheng <binch...@e108451-lin.cambridge.arm.com>
Date: Wed, 25 Apr 2018 16:30:41 +0100
Subject: [PATCH 6/6] pcom-reg-pressure-20180428

---
 gcc/tree-predcom.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 74 insertions(+)

diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c
index aeadbf7..60316e9 100644
--- a/gcc/tree-predcom.c
+++ b/gcc/tree-predcom.c
@@ -217,6 +217,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pass.h"
 #include "ssa.h"
 #include "gimple-pretty-print.h"
+#include "stor-layout.h"
 #include "alias.h"
 #include "fold-const.h"
 #include "cfgloop.h"
@@ -227,6 +228,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-loop-ivopts.h"
 #include "tree-ssa-loop-manip.h"
 #include "tree-ssa-loop-niter.h"
+#include "tree-ssa-live.h"
 #include "tree-ssa-loop.h"
 #include "tree-into-ssa.h"
 #include "tree-dfa.h"
@@ -242,6 +244,10 @@ along with GCC; see the file COPYING3.  If not see
 
 #define MAX_DISTANCE (target_avail_regs[GENERAL_REGS] < 16 ? 4 : 8)
 
+/* The ratio by which register pressure check is relaxed.  */
+
+#define REG_RELAX_RATIO (2)
+
 /* Data references (or phi nodes that carry data reference values across
    loop iterations).  */
 
@@ -3156,6 +3162,59 @@ insert_init_seqs (struct loop *loop, vec<chain_p> chains)
       }
 }
 
+/* Prune chains causing high register pressure.  */
+
+static void
+prune_chains (vec<chain_p> *chains, unsigned *max_pressure)
+{
+  bool pruned_p = false;
+  machine_mode mode;
+  enum reg_class cl;
+  unsigned i, new_pressure;
+
+  for (i = 0; i < chains->length ();)
+    {
+      chain_p chain = (*chains)[i];
+      /* Always allow combined chain and zero-length chain.  */
+      if (chain->combined || chain->type == CT_COMBINATION
+	  || chain->length == 0 || chain->type == CT_STORE_STORE)
+	{
+	  i++;
+	  continue;
+	}
+
+      gcc_assert (chain->refs.length () > 0);
+      mode = TYPE_MODE (TREE_TYPE (chain->refs[0]->ref->ref));
+      /* Bypass chain that doesn't contribute to any reg_class, although
+	 something could be wrong when mapping type mode to reg_class.  */
+      if (ira_mode_classes[mode] == NO_REGS)
+	{
+	  i++;
+	  continue;
+	}
+
+      cl = ira_pressure_class_translate[ira_mode_classes[mode]];
+      /* Prune chain if it causes higher register pressure than available
+	 registers; otherwise keep the chain and update register pressure
+	 information.  */
+      new_pressure = max_pressure[cl] + chain->length - 1;
+      if (new_pressure <= target_avail_regs[cl] * REG_RELAX_RATIO)
+	{
+	  i++;
+	  max_pressure[cl] = new_pressure;
+	}
+      else
+	{
+	  release_chain (chain);
+	  chains->unordered_remove (i);
+	  pruned_p = true;
+	}
+    }
+
+  if (pruned_p && dump_file && (dump_flags & TDF_DETAILS))
+    fprintf (dump_file, "Prune chain because of high reg pressure\n");
+}
+
 /* Performs predictive commoning for LOOP.  Sets bit 1<<0 of return value
    if LOOP was unrolled; Sets bit 1<<1 of return value if loop closed ssa
    form was corrupted.  */
@@ -3171,6 +3230,9 @@ tree_predictive_commoning_loop (struct loop *loop)
   struct tree_niter_desc desc;
   bool unroll = false, loop_closed_ssa = false;
   edge exit;
+  lr_region *region;
+  unsigned max_pressure[N_REG_CLASSES];
+  bool high_pressure_p;
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     fprintf (dump_file, "Processing loop %d\n",  loop->num);
@@ -3239,6 +3301,11 @@ tree_predictive_commoning_loop (struct loop *loop)
   /* Try to combine the chains that are always worked with together.  */
   try_combine_chains (loop, &chains);
 
+  region = new lr_region (loop, max_pressure, NULL, NULL, NULL);
+  high_pressure_p = region->calculate_pressure ();
+  delete region;
+  prune_chains (&chains, max_pressure);
+
   insert_init_seqs (loop, chains);
 
   if (dump_file && (dump_flags & TDF_DETAILS))
@@ -3250,6 +3317,13 @@ tree_predictive_commoning_loop (struct loop *loop)
   /* Determine the unroll factor, and if the loop should be unrolled, ensure
      that its number of iterations is divisible by the factor.  */
   unroll_factor = determine_unroll_factor (chains);
+  /* Force to not unroll if register pressure is high.  */
+  if (high_pressure_p && unroll_factor > 1)
+    {
+      unroll_factor = 1;
+      if (dump_file && (dump_flags & TDF_DETAILS))
+	fprintf (dump_file, "Force to not unroll because of high reg pressure\n");
+    }
   scev_reset ();
   unroll = (unroll_factor > 1
 	    && can_unroll_loop_p (loop, unroll_factor, &desc));
-- 
1.9.1

Reply via email to