This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH, loop2_invariant, 1/2] Check only one register class
- From: Zhenqiang Chen <zhenqiang dot chen at linaro dot org>
- To: Steven Bosscher <stevenb dot gcc at gmail dot com>
- Cc: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 11 Jun 2014 18:05:17 +0800
- Subject: Re: [PATCH, loop2_invariant, 1/2] Check only one register class
- Authentication-results: sourceware.org; auth=none
- References: <CACgzC7AM5DkDyibuCuTJp=DosH7q8fRM3TfEz_6WGkSYtkNLZA at mail dot gmail dot com> <CABu31nM26YT4d-iG1GQFJcdd4wnT+oqK89OhNUcfcfKwj9fP-g at mail dot gmail dot com>
On 10 June 2014 19:06, Steven Bosscher <stevenb.gcc@gmail.com> wrote:
> On Tue, Jun 10, 2014 at 11:22 AM, Zhenqiang Chen wrote:
>> Hi,
>>
>> For loop2-invariant pass, when flag_ira_loop_pressure is enabled,
>> function gain_for_invariant checks the pressures of all register
>> classes. This does not make sense since one invariant might impact
>> only one register class.
>>
>> The patch enhances functions get_inv_cost and gain_for_invariant to
>> check only the register pressure of the invariant if possible.
>
> This patch may work for targets with more-or-less orthogonal reg
> classes, but not if there is a lot of overlap between reg classes.
Yes. I need check the overlap between reg classes.
Patch is updated to check all overlap reg classes by reg_classes_intersect_p:
diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c
index c76a2a0..6e43b49 100644
--- a/gcc/loop-invariant.c
+++ b/gcc/loop-invariant.c
@@ -1092,16 +1092,22 @@ get_pressure_class_and_nregs (rtx insn, int *nregs)
}
/* Calculates cost and number of registers needed for moving invariant INV
- out of the loop and stores them to *COST and *REGS_NEEDED. */
+ out of the loop and stores them to *COST and *REGS_NEEDED. *CL will be
+ the REG_CLASS of INV. Return
+ 0: if INV is invalid.
+ 1: if INV and its depends_on have same reg_class
+ > 1: if INV and its depends_on have different reg_classes. */
-static void
-get_inv_cost (struct invariant *inv, int *comp_cost, unsigned *regs_needed)
+static int
+get_inv_cost (struct invariant *inv, int *comp_cost, unsigned *regs_needed,
+ enum reg_class *cl)
{
int i, acomp_cost;
unsigned aregs_needed[N_REG_CLASSES];
unsigned depno;
struct invariant *dep;
bitmap_iterator bi;
+ int ret = 2;
/* Find the representative of the class of the equivalent invariants. */
inv = invariants[inv->eqto];
@@ -1117,7 +1123,7 @@ get_inv_cost (struct invariant *inv, int
*comp_cost, unsigned *regs_needed)
if (inv->move
|| inv->stamp == actual_stamp)
- return;
+ return 0;
inv->stamp = actual_stamp;
if (! flag_ira_loop_pressure)
@@ -1129,6 +1135,8 @@ get_inv_cost (struct invariant *inv, int
*comp_cost, unsigned *regs_needed)
pressure_class = get_pressure_class_and_nregs (inv->insn, &nregs);
regs_needed[pressure_class] += nregs;
+ *cl = pressure_class;
+ ret = 1;
}
if (!inv->cheap_address
@@ -1169,6 +1177,8 @@ get_inv_cost (struct invariant *inv, int
*comp_cost, unsigned *regs_needed)
EXECUTE_IF_SET_IN_BITMAP (inv->depends_on, 0, depno, bi)
{
bool check_p;
+ enum reg_class dep_cl = ALL_REGS;
+ int dep_ret;
dep = invariants[depno];
@@ -1176,7 +1186,7 @@ get_inv_cost (struct invariant *inv, int
*comp_cost, unsigned *regs_needed)
if (dep->move)
continue;
- get_inv_cost (dep, &acomp_cost, aregs_needed);
+ dep_ret = get_inv_cost (dep, &acomp_cost, aregs_needed, &dep_cl);
if (! flag_ira_loop_pressure)
check_p = aregs_needed[0] != 0;
@@ -1186,6 +1196,12 @@ get_inv_cost (struct invariant *inv, int
*comp_cost, unsigned *regs_needed)
if (aregs_needed[ira_pressure_classes[i]] != 0)
break;
check_p = i < ira_pressure_classes_num;
+
+ if ((dep_ret > 1) || ((dep_ret == 1) && (*cl != dep_cl)))
+ {
+ *cl = ALL_REGS;
+ ret ++;
+ }
}
if (check_p
/* We need to check always_executed, since if the original value of
@@ -1219,6 +1235,7 @@ get_inv_cost (struct invariant *inv, int
*comp_cost, unsigned *regs_needed)
}
(*comp_cost) += acomp_cost;
}
+ return ret;
}
/* Calculates gain for eliminating invariant INV. REGS_USED is the number
@@ -1233,10 +1250,12 @@ gain_for_invariant (struct invariant *inv,
unsigned *regs_needed,
bool speed, bool call_p)
{
int comp_cost, size_cost;
+ enum reg_class cl;
+ int ret;
actual_stamp++;
- get_inv_cost (inv, &comp_cost, regs_needed);
+ ret = get_inv_cost (inv, &comp_cost, regs_needed, &cl);
if (! flag_ira_loop_pressure)
{
@@ -1245,6 +1264,11 @@ gain_for_invariant (struct invariant *inv,
unsigned *regs_needed,
- estimate_reg_pressure_cost (new_regs[0],
regs_used, speed, call_p));
}
+ else if (ret == 0)
+ return -1;
+ else if ((ret == 1) && (cl == NO_REGS))
+ /* Hoist it anyway since it does not impact register pressure. */
+ return 1;
else
{
int i;
@@ -1253,6 +1277,10 @@ gain_for_invariant (struct invariant *inv,
unsigned *regs_needed,
for (i = 0; i < ira_pressure_classes_num; i++)
{
pressure_class = ira_pressure_classes[i];
+
+ if (!reg_classes_intersect_p (pressure_class, cl))
+ continue;
+
if ((int) new_regs[pressure_class]
+ (int) regs_needed[pressure_class]
+ LOOP_DATA (curr_loop)->max_reg_pressure[pressure_class]