From efaf512c94161056ad9834cf2d4f53d25e77aa2d Mon Sep 17 00:00:00 2001 From: Vladimir Makarov Date: Mon, 4 Nov 2013 16:12:29 +0000 Subject: [PATCH] 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 PR rtl-optimization/58968 * lra-spills.c (return_regno_p): New function. (lra_final_code_change): Use it. 2013-11-04 Vladimir Makarov PR rtl-optimization/58968 * gfortran.dg/pr58968.f: New From-SVN: r204353 --- gcc/ChangeLog | 6 ++ gcc/lra-spills.c | 69 ++++++++++++++------- gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gfortran.dg/pr58968.f | 96 +++++++++++++++++++++++++++++ 4 files changed, 153 insertions(+), 23 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr58968.f diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 32e4c30dc54..7e0b752c3ed 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2013-11-04 Vladimir Makarov + + PR rtl-optimization/58968 + * lra-spills.c (return_regno_p): New function. + (lra_final_code_change): Use it. + 2013-11-04 Joseph Myers * doc/cpp.texi (__GCC_IEC_559, __GCC_IEC_559_COMPLEX): Document diff --git a/gcc/lra-spills.c b/gcc/lra-spills.c index 391419fa09e..4ab10c25b98 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 4da6480faa3..1f487d7f822 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-11-04 Vladimir Makarov + + PR rtl-optimization/58968 + * gfortran.dg/pr58968.f: New + 2013-11-04 Marek Polacek PR c++/58979 diff --git a/gcc/testsuite/gfortran.dg/pr58968.f b/gcc/testsuite/gfortran.dg/pr58968.f new file mode 100644 index 00000000000..db06d50fa27 --- /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 -- 2.30.2