diff options
author | Zhenqiang Chen <zhenqiang.chen@linaro.org> | 2014-06-30 03:36:47 +0000 |
---|---|---|
committer | Zhenqiang Chen <zqchen@gcc.gnu.org> | 2014-06-30 03:36:47 +0000 |
commit | 51a6916856bf73654ff57693871f77dfc02a6c1a (patch) | |
tree | 500d8005ad0d4e829d98dec7aeaf318585727526 /gcc | |
parent | 22fa5b71aa4ed902474f03267ffa30f3e9981b82 (diff) | |
download | gcc-51a6916856bf73654ff57693871f77dfc02a6c1a.zip gcc-51a6916856bf73654ff57693871f77dfc02a6c1a.tar.gz gcc-51a6916856bf73654ff57693871f77dfc02a6c1a.tar.bz2 |
loop-invariant.c (get_inv_cost): Handle register class.
ChangeLog:
2014-06-30 Zhenqiang Chen <zhenqiang.chen@linaro.org>
* loop-invariant.c (get_inv_cost): Handle register class.
(gain_for_invariant): Check the register pressure of the inv
and its overlapped register class, other than all.
testsuite/ChangeLog:
2014-06-30 Zhenqiang Chen <zhenqiang.chen@linaro.org>
* ira-loop-pressure.c: New test.
From-SVN: r212135
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/loop-invariant.c | 40 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/ira-loop-pressure.c | 32 |
4 files changed, 76 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 14f6769..4cc167a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2014-06-30 Zhenqiang Chen <zhenqiang.chen@linaro.org> + + * loop-invariant.c (get_inv_cost): Handle register class. + (gain_for_invariant): Check the register pressure of the inv + and its overlapped register class, other than all. + 2014-06-30 Gerald Pfeifer <gerald@pfeifer.com> * doc/invoke.texi (Optimize Options): Fix descriptions of diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c index 3852c6b..d47d461 100644 --- a/gcc/loop-invariant.c +++ b/gcc/loop-invariant.c @@ -1087,16 +1087,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 + -1: if INV is invalid. + 0: 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 = 1; /* Find the representative of the class of the equivalent invariants. */ inv = invariants[inv->eqto]; @@ -1112,7 +1118,7 @@ get_inv_cost (struct invariant *inv, int *comp_cost, unsigned *regs_needed) if (inv->move || inv->stamp == actual_stamp) - return; + return -1; inv->stamp = actual_stamp; if (! flag_ira_loop_pressure) @@ -1124,6 +1130,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 = 0; } if (!inv->cheap_address @@ -1164,6 +1172,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]; @@ -1171,7 +1181,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; @@ -1181,6 +1191,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 == 0) && (*cl != dep_cl))) + { + *cl = ALL_REGS; + ret = 1; + } } if (check_p /* We need to check always_executed, since if the original value of @@ -1214,6 +1230,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 @@ -1228,10 +1245,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) { @@ -1240,6 +1259,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 == 0) && (cl == NO_REGS)) + /* Hoist it anyway since it does not impact register pressure. */ + return 1; else { int i; @@ -1248,6 +1272,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] diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 86276d9..5a9d73a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-06-30 Zhenqiang Chen <zhenqiang.chen@linaro.org> + + * ira-loop-pressure.c: New test. + 2014-06-29 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> PR fortran/36275 diff --git a/gcc/testsuite/gcc.dg/ira-loop-pressure.c b/gcc/testsuite/gcc.dg/ira-loop-pressure.c new file mode 100644 index 0000000..7ef4fa7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ira-loop-pressure.c @@ -0,0 +1,32 @@ +/* Loop2_invariants pass should distinguish register pressures of different + register classes. In this case, register pressue of INT is high. But + we can still move the FP invariant out of the loop. */ + +/* { dg-do compile { target { x86_64-*-* && lp64 } } } */ +/* { dg-options "-O2 -fira-loop-pressure -fdump-rtl-loop2_invariant " } */ + +float tt; +extern void foo2 (int *, int *, int *, int *, int *, int *); +extern int foo3 (int, int, int, int, int, int); +int foo (int a, int b, int c, int d) +{ + int i = a; + int t1, t2, t3, t4, t5, t6; + t1 = t2 = t3 = t4 = t5 = t6 = 0; + + for (; i > 0; i += c) + { + tt += 123456.0; + if (d > t1 + t2) + tt = 3.0; + foo2 (&t1, &t2, &t3, &t4, &t5, &t6); + t1 += t3 + t4 + a + b; + t2 -= t5 - t6 - c - d; + } + + return foo3 (t1, t2, t3, t4, t5, t6); +} + +/* { dg-final { scan-rtl-dump "Decided to move invariant" "loop2_invariant" } } */ +/* { dg-final { cleanup-rtl-dump "loop2_invariant" } } */ + |