]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
2013-11-04 Vladimir Makarov <vmakarov@redhat.com>
authorvmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 4 Nov 2013 16:12:29 +0000 (16:12 +0000)
committervmakarov <vmakarov@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 4 Nov 2013 16:12:29 +0000 (16:12 +0000)
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

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@204353 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/lra-spills.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/pr58968.f [new file with mode: 0644]

index 32e4c30dc54c1bf44819cbfcb27b7fab6fb08bfb..7e0b752c3ed486f2db6a649edeb6e0a9fa997a8c 100644 (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>
 
        * doc/cpp.texi (__GCC_IEC_559, __GCC_IEC_559_COMPLEX): Document
index 391419fa09e80c77ab1d8187c061e62636aa343f..4ab10c25b98ed3d7f74604a215bc162d90526603 100644 (file)
@@ -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);
-           }
        }
 }
index 4da6480faa3a55b26936912812a75d915658f236..1f487d7f82245e99244b6c9aac481487b372d23f 100644 (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>
 
        PR c++/58979
diff --git a/gcc/testsuite/gfortran.dg/pr58968.f b/gcc/testsuite/gfortran.dg/pr58968.f
new file mode 100644 (file)
index 0000000..db06d50
--- /dev/null
@@ -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