Hi,
This is the second patch computing available/clobber registers for register
classes.
It's the same as the original patch posted
@https://gcc.gnu.org/ml/gcc-patches/2017-05/msg01022.html
Bootstrap and test on x86_64 and AArch64 ongoing. Any comments?
Thanks,
bin
2017-04-27 Bin Cheng <bin.ch...@arm.com>
* cfgloop.h (struct target_cfgloop): Change x_target_avail_regs and
x_target_clobbered_regs into array fields.
(init_avail_clobber_regs): New declaration.
* cfgloopanal.c (memmodel.h, ira.h): Include header files.
(init_set_costs): Remove computation for old x_target_avail_regs and
x_target_clobbered_regs fields.
(init_avail_clobber_regs): New function.
(estimate_reg_pressure_cost): Update the uses.
* toplev.c (cfgloop.h): Update comment why the header file is needed.
(backend_init_target): Call init_avail_clobber_regs.
* tree-predcom.c (memmodel.h, ira.h): Include header files.
(MAX_DISTANCE): Update the use.
* tree-ssa-loop-ivopts.c (AVAILABLE_REGS, CLOBBERED_REGS): New marco.
(ivopts_estimate_reg_pressure, determine_set_costs): Update the uses.
From 47a2074d21f4b28b4c38233628e94bcaef9ed40d Mon Sep 17 00:00:00 2001
From: Bin Cheng <binch...@e108451-lin.cambridge.arm.com>
Date: Thu, 19 Apr 2018 15:54:14 +0100
Subject: [PATCH 2/6] init-avail_clob-regs-20180428.txt
---
gcc/cfgloop.h | 10 ++++---
gcc/cfgloopanal.c | 68 +++++++++++++++++++++++++++++++++++-----------
gcc/toplev.c | 3 +-
gcc/tree-predcom.c | 4 ++-
gcc/tree-ssa-loop-ivopts.c | 14 ++++++----
5 files changed, 72 insertions(+), 27 deletions(-)
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index af9bfab..3d06e1c 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -773,11 +773,12 @@ loop_iterator::~loop_iterator ()
/* The properties of the target. */
struct target_cfgloop {
- /* Number of available registers. */
- unsigned x_target_avail_regs;
+ /* Number of available registers per register pressure class. */
+ unsigned x_target_avail_regs[N_REG_CLASSES];
- /* Number of available registers that are call-clobbered. */
- unsigned x_target_clobbered_regs;
+ /* Number of available registers that are call-clobbered, per register
+ pressure class. */
+ unsigned x_target_clobbered_regs[N_REG_CLASSES];
/* Number of registers reserved for temporary expressions. */
unsigned x_target_res_regs;
@@ -812,6 +813,7 @@ extern struct target_cfgloop *this_target_cfgloop;
invariant motion. */
extern unsigned estimate_reg_pressure_cost (unsigned, unsigned, bool, bool);
extern void init_set_costs (void);
+extern void init_avail_clobber_regs (void);
/* Loop optimizer initialization. */
extern void loop_optimizer_init (unsigned);
diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c
index 3af0b2d..20010bb 100644
--- a/gcc/cfgloopanal.c
+++ b/gcc/cfgloopanal.c
@@ -22,6 +22,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 "predict.h"
#include "memmodel.h"
@@ -344,20 +346,6 @@ init_set_costs (void)
rtx reg2 = gen_raw_REG (SImode, LAST_VIRTUAL_REGISTER + 2);
rtx addr = gen_raw_REG (Pmode, LAST_VIRTUAL_REGISTER + 3);
rtx mem = validize_mem (gen_rtx_MEM (SImode, addr));
- unsigned i;
-
- target_avail_regs = 0;
- target_clobbered_regs = 0;
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i)
- && !fixed_regs[i])
- {
- target_avail_regs++;
- if (call_used_regs[i])
- target_clobbered_regs++;
- }
-
- target_res_regs = 3;
for (speed = 0; speed < 2; speed++)
{
@@ -387,6 +375,54 @@ init_set_costs (void)
default_rtl_profile ();
}
+/* Initialize available, clobbered register for each register classes. */
+
+void
+init_avail_clobber_regs (void)
+{
+ int j;
+ unsigned i;
+ bool general_regs_presented_p = false;
+
+ /* Check if GENERAL_REGS is one of pressure classes. */
+ for (j = 0; j < ira_pressure_classes_num; j++)
+ {
+ target_avail_regs[j] = 0;
+ target_clobbered_regs[j] = 0;
+ if (ira_pressure_classes[j] == GENERAL_REGS)
+ general_regs_presented_p = true;
+ }
+ target_avail_regs[GENERAL_REGS] = 0;
+ target_clobbered_regs[GENERAL_REGS] = 0;
+
+ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ {
+ if (fixed_regs[i])
+ continue;
+
+ bool call_used = call_used_regs[i];
+
+ for (j = 0; j < ira_pressure_classes_num; j++)
+ if (TEST_HARD_REG_BIT (reg_class_contents[ira_pressure_classes[j]], i))
+ {
+ target_avail_regs[ira_pressure_classes[j]]++;
+ if (call_used)
+ target_clobbered_regs[ira_pressure_classes[j]]++;
+ }
+
+ /* Compute pressure information for GENERAL_REGS separately. */
+ if (!general_regs_presented_p)
+ if (TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i))
+ {
+ target_avail_regs[GENERAL_REGS]++;
+ if (call_used)
+ target_clobbered_regs[GENERAL_REGS]++;
+ }
+ }
+
+ target_res_regs = 3;
+}
+
/* Estimates cost of increased register pressure caused by making N_NEW new
registers live around the loop. N_OLD is the number of registers live
around the loop. If CALL_P is true, also take into account that
@@ -399,12 +435,12 @@ estimate_reg_pressure_cost (unsigned n_new, unsigned n_old, bool speed,
{
unsigned cost;
unsigned regs_needed = n_new + n_old;
- unsigned available_regs = target_avail_regs;
+ unsigned available_regs = target_avail_regs[GENERAL_REGS];
/* If there is a call in the loop body, the call-clobbered registers
are not available for loop invariants. */
if (call_p)
- available_regs = available_regs - target_clobbered_regs;
+ available_regs = available_regs - target_clobbered_regs[GENERAL_REGS];
/* If we have enough registers, we should use them and not restrict
the transformations unnecessarily. */
diff --git a/gcc/toplev.c b/gcc/toplev.c
index b066bcc..0a2662b 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -59,7 +59,7 @@ along with GCC; see the file COPYING3. If not see
#include "debug.h"
#include "common/common-target.h"
#include "langhooks.h"
-#include "cfgloop.h" /* for init_set_costs */
+#include "cfgloop.h" /* For init_set_costs and init_avail_clobber_regs. */
#include "hosthooks.h"
#include "opts.h"
#include "opts-diagnostic.h"
@@ -1797,6 +1797,7 @@ backend_init_target (void)
init_expr_target ();
ira_init ();
+ init_avail_clobber_regs ();
/* We may need to recompute regno_save_code[] and regno_restore_code[]
after a mode change as well. */
diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c
index 2bde732..aeadbf7 100644
--- a/gcc/tree-predcom.c
+++ b/gcc/tree-predcom.c
@@ -209,6 +209,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 "predict.h"
@@ -238,7 +240,7 @@ along with GCC; see the file COPYING3. If not see
/* The maximum number of iterations between the considered memory
references. */
-#define MAX_DISTANCE (target_avail_regs < 16 ? 4 : 8)
+#define MAX_DISTANCE (target_avail_regs[GENERAL_REGS] < 16 ? 4 : 8)
/* Data references (or phi nodes that carry data reference values across
loop iterations). */
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index b313571..6e14933 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -135,6 +135,10 @@ avg_loop_niter (struct loop *loop)
return niter;
}
+/* Information about target general registers. */
+#define AVAILABLE_REGS (target_avail_regs[GENERAL_REGS])
+#define CLOBBERED_REGS (target_clobbered_regs[GENERAL_REGS])
+
struct iv_use;
/* Representation of the induction variable. */
@@ -5627,13 +5631,13 @@ ivopts_estimate_reg_pressure (struct ivopts_data *data, unsigned n_invs,
{
unsigned cost;
unsigned n_old = data->regs_used, n_new = n_invs + n_cands;
- unsigned regs_needed = n_new + n_old, available_regs = target_avail_regs;
+ unsigned regs_needed = n_new + n_old, available_regs = AVAILABLE_REGS;
bool speed = data->speed;
/* If there is a call in the loop body, the call-clobbered registers
are not available for loop invariants. */
if (data->body_includes_call)
- available_regs = available_regs - target_clobbered_regs;
+ available_regs = available_regs - CLOBBERED_REGS;
/* If we have enough registers. */
if (regs_needed + target_res_regs < available_regs)
@@ -5674,8 +5678,8 @@ determine_set_costs (struct ivopts_data *data)
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "<Global Costs>:\n");
- fprintf (dump_file, " target_avail_regs %d\n", target_avail_regs);
- fprintf (dump_file, " target_clobbered_regs %d\n", target_clobbered_regs);
+ fprintf (dump_file, " target_avail_regs %d\n", AVAILABLE_REGS);
+ fprintf (dump_file, " target_clobbered_regs %d\n", CLOBBERED_REGS);
fprintf (dump_file, " target_reg_cost %d\n", target_reg_cost[data->speed]);
fprintf (dump_file, " target_spill_cost %d\n", target_spill_cost[data->speed]);
}
@@ -5715,7 +5719,7 @@ determine_set_costs (struct ivopts_data *data)
{
fprintf (dump_file, " cost for size:\n");
fprintf (dump_file, " ivs\tcost\n");
- for (j = 0; j <= 2 * target_avail_regs; j++)
+ for (j = 0; j <= 2 * AVAILABLE_REGS; j++)
fprintf (dump_file, " %d\t%d\n", j,
ivopts_estimate_reg_pressure (data, 0, j));
fprintf (dump_file, "\n");
--
1.9.1