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
This commit is contained in:
Vladimir Makarov 2013-11-04 16:12:29 +00:00 committed by Vladimir Makarov
parent 55a7f02f06
commit efaf512c94
4 changed files with 153 additions and 23 deletions

View File

@ -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> 2013-11-04 Joseph Myers <joseph@codesourcery.com>
* doc/cpp.texi (__GCC_IEC_559, __GCC_IEC_559_COMPLEX): Document * doc/cpp.texi (__GCC_IEC_559, __GCC_IEC_559_COMPLEX): Document

View File

@ -618,6 +618,33 @@ alter_subregs (rtx *loc, bool final_p)
return res; 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 /* Final change of pseudos got hard registers into the corresponding
hard registers and removing temporary clobbers. */ hard registers and removing temporary clobbers. */
void void
@ -625,7 +652,7 @@ lra_final_code_change (void)
{ {
int i, hard_regno; int i, hard_regno;
basic_block bb; basic_block bb;
rtx insn, curr, set; rtx insn, curr;
int max_regno = max_reg_num (); int max_regno = max_reg_num ();
for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++) 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) FOR_BB_INSNS_SAFE (bb, insn, curr)
if (INSN_P (insn)) if (INSN_P (insn))
{ {
bool change_p;
rtx pat = PATTERN (insn); rtx pat = PATTERN (insn);
if (GET_CODE (pat) == CLOBBER && LRA_TEMP_CLOBBER_P (pat)) if (GET_CODE (pat) == CLOBBER && LRA_TEMP_CLOBBER_P (pat))
@ -649,12 +675,24 @@ lra_final_code_change (void)
continue; continue;
} }
set = single_set (insn); /* IRA can generate move insns involving pseudos. It is
change_p = (set != NULL better remove them earlier to speed up compiler a bit.
&& REG_P (SET_SRC (set)) && REG_P (SET_DEST (set)) It is also better to do it here as they might not pass
&& REGNO (SET_SRC (set)) >= FIRST_PSEUDO_REGISTER final RTL check in LRA, (e.g. insn moving a control
&& REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER); 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); lra_insn_recog_data_t id = lra_get_insn_recog_data (insn);
struct lra_static_insn_data *static_id = id->insn_static_data; struct lra_static_insn_data *static_id = id->insn_static_data;
bool insn_change_p = false; bool insn_change_p = false;
@ -668,20 +706,5 @@ lra_final_code_change (void)
} }
if (insn_change_p) if (insn_change_p)
lra_update_operator_dups (id); 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);
}
} }
} }

View File

@ -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> 2013-11-04 Marek Polacek <polacek@redhat.com>
PR c++/58979 PR c++/58979

View File

@ -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