aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2013-11-04 16:12:29 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2013-11-04 16:12:29 +0000
commitefaf512c94161056ad9834cf2d4f53d25e77aa2d (patch)
tree7ba1b744ef9280834c03863b29bc4aac6b0378e3
parent55a7f02f06688ffea709e2b3de25004f10b8708d (diff)
downloadgcc-efaf512c94161056ad9834cf2d4f53d25e77aa2d.zip
gcc-efaf512c94161056ad9834cf2d4f53d25e77aa2d.tar.gz
gcc-efaf512c94161056ad9834cf2d4f53d25e77aa2d.tar.bz2
re PR rtl-optimization/58968 (Powerpc -mlra cannot compile ormas1.f in gamess Spec 2006 with -m32 -mcpu=power7 -O3 -mlra -w -ffast-math -funroll-loops)
2013-11-04 Vladimir Makarov <vmakarov@redhat.com> PR rtl-optimization/58968 * lra-spills.c (return_regno_p): New function. (lra_final_code_change): Use it. 2013-11-04 Vladimir Makarov <vmakarov@redhat.com> PR rtl-optimization/58968 * gfortran.dg/pr58968.f: New From-SVN: r204353
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/lra-spills.c69
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/pr58968.f96
4 files changed, 153 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 32e4c30..7e0b752 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2013-11-04 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR rtl-optimization/58968
+ * lra-spills.c (return_regno_p): New function.
+ (lra_final_code_change): Use it.
+
2013-11-04 Joseph Myers <joseph@codesourcery.com>
* doc/cpp.texi (__GCC_IEC_559, __GCC_IEC_559_COMPLEX): Document
diff --git a/gcc/lra-spills.c b/gcc/lra-spills.c
index 391419f..4ab10c2 100644
--- a/gcc/lra-spills.c
+++ b/gcc/lra-spills.c
@@ -618,6 +618,33 @@ alter_subregs (rtx *loc, bool final_p)
return res;
}
+/* Return true if REGNO is used for return in the current
+ function. */
+static bool
+return_regno_p (unsigned int regno)
+{
+ rtx outgoing = crtl->return_rtx;
+
+ if (! outgoing)
+ return false;
+
+ if (REG_P (outgoing))
+ return REGNO (outgoing) == regno;
+ else if (GET_CODE (outgoing) == PARALLEL)
+ {
+ int i;
+
+ for (i = 0; i < XVECLEN (outgoing, 0); i++)
+ {
+ rtx x = XEXP (XVECEXP (outgoing, 0, i), 0);
+
+ if (REG_P (x) && REGNO (x) == regno)
+ return true;
+ }
+ }
+ return false;
+}
+
/* Final change of pseudos got hard registers into the corresponding
hard registers and removing temporary clobbers. */
void
@@ -625,7 +652,7 @@ lra_final_code_change (void)
{
int i, hard_regno;
basic_block bb;
- rtx insn, curr, set;
+ rtx insn, curr;
int max_regno = max_reg_num ();
for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
@@ -636,7 +663,6 @@ lra_final_code_change (void)
FOR_BB_INSNS_SAFE (bb, insn, curr)
if (INSN_P (insn))
{
- bool change_p;
rtx pat = PATTERN (insn);
if (GET_CODE (pat) == CLOBBER && LRA_TEMP_CLOBBER_P (pat))
@@ -649,12 +675,24 @@ lra_final_code_change (void)
continue;
}
- set = single_set (insn);
- change_p = (set != NULL
- && REG_P (SET_SRC (set)) && REG_P (SET_DEST (set))
- && REGNO (SET_SRC (set)) >= FIRST_PSEUDO_REGISTER
- && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER);
-
+ /* IRA can generate move insns involving pseudos. It is
+ better remove them earlier to speed up compiler a bit.
+ It is also better to do it here as they might not pass
+ final RTL check in LRA, (e.g. insn moving a control
+ register into itself). So remove an useless move insn
+ unless next insn is USE marking the return reg (we should
+ save this as some subsequent optimizations assume that
+ such original insns are saved). */
+ if (NONJUMP_INSN_P (insn) && GET_CODE (pat) == SET
+ && REG_P (SET_SRC (pat)) && REG_P (SET_DEST (pat))
+ && REGNO (SET_SRC (pat)) == REGNO (SET_DEST (pat))
+ && ! return_regno_p (REGNO (SET_SRC (pat))))
+ {
+ lra_invalidate_insn_data (insn);
+ delete_insn (insn);
+ continue;
+ }
+
lra_insn_recog_data_t id = lra_get_insn_recog_data (insn);
struct lra_static_insn_data *static_id = id->insn_static_data;
bool insn_change_p = false;
@@ -668,20 +706,5 @@ lra_final_code_change (void)
}
if (insn_change_p)
lra_update_operator_dups (id);
-
- if (change_p && REGNO (SET_SRC (set)) == REGNO (SET_DEST (set)))
- {
- /* Remove an useless move insn but only involving
- pseudos as some subsequent optimizations are based on
- that move insns involving originally hard registers
- are preserved. IRA can generate move insns involving
- pseudos. It is better remove them earlier to speed
- up compiler a bit. It is also better to do it here
- as they might not pass final RTL check in LRA,
- (e.g. insn moving a control register into
- itself). */
- lra_invalidate_insn_data (insn);
- delete_insn (insn);
- }
}
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4da6480..1f487d7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2013-11-04 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR rtl-optimization/58968
+ * gfortran.dg/pr58968.f: New
+
2013-11-04 Marek Polacek <polacek@redhat.com>
PR c++/58979
diff --git a/gcc/testsuite/gfortran.dg/pr58968.f b/gcc/testsuite/gfortran.dg/pr58968.f
new file mode 100644
index 0000000..db06d50
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr58968.f
@@ -0,0 +1,96 @@
+C PR rtl-optimization/58968.f
+C { dg-do compile { target powerpc*-*-*} }
+C { dg-options "-mcpu=power7 -O3 -w -ffast-math -funroll-loops" }
+ SUBROUTINE MAKTABS(IW,SOME,LBOX1,LBOX2,LBOX3,NSPACE,NA,NB,
+ * LBST,X,
+ * NX,IAMA,IAMI,IBMA,IBMI,MNUM,IDIM,MSTA,IBO,
+ * IDSYM,ISYM1,NSYM,
+ * NACT,LWRK,KTAB,LGMUL,
+ * LCON,LCOA,LCOB,
+ * LANDET,LBNDET,NAST,NBST,LSYMA,LSYMB,LGCOM,
+ * MINI,MAXI,LSPA,LSPB,LDISB,
+ * LSAS,LSBS,LSAC,LSBC,
+ * ITGA,ITGB,IAST,IBST,NCI,NA1EX,NB1EX,FDIRCT)
+ IMPLICIT DOUBLE PRECISION(A-H,O-Z)
+ LOGICAL SOME
+ DIMENSION LBOX1(NSPACE),LBOX2(NSPACE),LBOX3(NSPACE),LBST(NSPACE)
+ DIMENSION X(NX)
+ DIMENSION IAMA(NSPACE),IAMI(NSPACE),IBMA(NSPACE),IBMI(NSPACE)
+ DIMENSION MNUM(NSPACE),IDIM(NSPACE),MSTA(NSPACE+1),IBO(NACT)
+ DIMENSION LWRK(43),KTAB(NSYM),LGMUL(NSYM,NSYM)
+ DIMENSION LCON(NA)
+ DIMENSION LCOA(NSYM,ITGA),LCOB(NSYM,ITGB)
+ DIMENSION LANDET(NSPACE,ITGA),LBNDET(NSPACE,ITGB)
+ DIMENSION NAST(ITGA+1),NBST(ITGB+1)
+ DIMENSION LSYMA(IAST),LSYMB(IBST)
+ DIMENSION LGCOM(ITGB,ITGA)
+ DIMENSION MINI(NSPACE),MAXI(NSPACE)
+ DIMENSION LSPA(IAST),LSPB(IBST)
+ DIMENSION LDISB(NSYM,ITGB,ITGA)
+ DIMENSION LSAS(NSYM+1,ITGA),LSBS(NSYM+1,ITGB)
+ DIMENSION LSAC(IAST),LSBC(IBST)
+ LOGICAL FDIRCT
+ LCOA = 0
+ LCOB = 0
+ ISTA1 = LBST(1)
+ CALL RESETCO(LBOX1,NSPACE,NB,IBMA,IBMI,LBOX2)
+ NAST(1) = 0
+ NBST(1) = 0
+ DO II=1,ITGA
+ ITOT = 1
+ DO JJ=1,NSPACE
+ ITOT = ITOT * LANDET(JJ,II)
+ ENDDO
+ NAST(II+1) = NAST(II) + ITOT
+ ENDDO
+ DO II=1,ITGB
+ ITOT = 1
+ DO JJ=1,NSPACE
+ ITOT = ITOT * LBNDET(JJ,II)
+ ENDDO
+ NBST(II+1) = NBST(II) + ITOT
+ ENDDO
+ ICOMP = 0
+ CALL RESETCO(LBOX1,NSPACE,NA,IAMA,IAMI,LBOX3)
+ NA1EX = 0
+ NB1EX = 0
+ CALL RESETCO(LBOX1,NSPACE,NB,IBMA,IBMI,LBOX3)
+ DO IIB = 1,ITGB
+ CALL RESETDE(LBOX1,NSPACE,NB,MSTA,LCON)
+ DO KKB=NBST(IIB)+1,NBST(IIB+1)
+ DO II=1,NSPACE
+ LBOX2(II) = LBOX1(II)
+ ENDDO
+ IEBS = NB+1
+ DO ISPB1=NSPACE,1,-1
+ IOC1 = LBOX1(ISPB1)
+ IEBE = IEBS - 1
+ IEBS = IEBS - IOC1
+ LBOX2(ISPB1) = LBOX2(ISPB1)-1
+ DO IB1=IEBE,IEBS,-1
+ IO1 = LCON(IB1)
+ IGBE = IEBE - LBOX1(ISPB1)
+ DO ISPB2=ISPB1,NSPACE
+ IGBS = IGBE + 1
+ IGBE = IGBE + LBOX1(ISPB2)
+ LBOX2(ISPB2) = LBOX2(ISPB2) + 1
+ IGBA = MAX(IB1+1,IGBS)
+ DO IGAP=IGBA,IGBE+1
+ DO JJ=ISTA,IEND
+ NB1EX = NB1EX + 1
+ ENDDO
+ ISTA = LCON(IGAP)+1
+ IEND = LCON(IGAP+1)-1
+ IF (IGAP.EQ.IGBE) IEND=MSTA(ISPB2+1)-1
+ ENDDO
+ LBOX2(ISPB2) = LBOX2(ISPB2) - 1
+ ENDDO
+ ENDDO
+ LBOX2(ISPB1) = LBOX2(ISPB1) + 1
+ ENDDO
+ CALL MOVEUP2(LBOX1,NSPACE,NB,MSTA,LCON)
+ ENDDO
+ CALL PUSHCO(LBOX1,NSPACE,NB,IBMA,IBMI,LBOX3,IEND)
+ ENDDO
+ RETURN
+ END