🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: gnu.gcc.bug
Article #6366

GCC patch #3

#6366
From: buc
Date: Tue, 05 Dec 1995 00:00
167 lines
5273 bytes
        *cse.c (fold_rtx): don`t eliminate regs storing const address

GCC:    2.7.0

(Our configuration:
        CPU:        mc68030/mc68882
        Computer:   BESTA   (similar to `mot3300 delta')
        System:     SVR3.1  (similar to sysV68)
        asm:        SGS  System V/68 R2V1  syntax  )

    We`ve found out a case, when GCC not efficiently chooses
addressing modes for insns.
    E.g.,

test #1
        ****file  foo1.c****

        extern long *A, *B;

        void foo( void ) {
                long *a = A, *b = B;
                *a++ = *b++;
                *a++ = *b++;
                *a++ = *b++;
                *a++ = *b++;
        }

        ********************

`gcc -S -O2 foo1.c'

result #1
        ****file foo1.s*****

                file  "foo1.c"
        text
                even
        global foo
        foo:
                mov.l A,%a1
                mov.l B,%a0
                mov.l (%a0)+,(%a1)+
                mov.l (%a0)+,(%a1)+
                mov.l (%a0)+,(%a1)+
                mov.l (%a0),(%a1)
                rts
                nop

        ********************

Everything is OK hear, but:

test #2
        ****file  foo2.c****

        extern long A[],B[];

        void foo( void ) {
                long *a = A, *b = B;
                *a++ = *b++;
                *a++ = *b++;
                *a++ = *b++;
                *a++ = *b++;
        }

        ********************

`gcc -S -O2 foo2.c'

result #2
        ****file foo2.s*****

                file  "kaka2.c"
        text
                even
        global foo
        foo:
                mov.l B,A
                mov.l B+4,A+4
                mov.l B+8,A+8
                mov.l B+12,A+12
                rts
                nop

        ********************

    That was a bad code, for instead of the fast two-byte`s insn
`mov.l (%a0+),(%a1)+'  the more slow ten-byte`s  `mov.l EA1.l EA2.l'
was used.
    The code damage takes place after cse compilation phase, when
regs and `a' and `b' variables are eliminated (last example).

    I think, many machines have increment, decrement or offset
addressing modes, which in similar cases are executed much more
efficiently than direct memory addressing. So, if a user define variables
(as `a' and `b' in the above example), then let these variables stay
variables. To generate codes similar to the second example, one may use
` A[0] = B[0]; A[1] = B[1]; ... ' etc.

    To fix the problem considered, one should patch the file cse.c :

`diff -p -c8' for cse.c:

*** cseOLD.c    Wed Nov 29 18:06:17 1995
--- cse.c       Wed Nov 29 18:05:16 1995
*************** fold_rtx (x, insn)
*** 5088,5112 ****
--- 5088,5136 ----
        rtx cheap_arg, expensive_arg;
        rtx replacements[2];
        int j;

        /* Most arguments are cheap, so handle them specially.  */
        switch (GET_CODE (arg))
          {
          case REG:
+
+       /* #if 0 ... #endif :
+          If there are some reasons for it to be a reg, let it be reg.
+
+          One of the reasons:
+          Try on machine, which has postincrement:
+             { extern int A[],B[];
+               int *a = A, *b = B;
+               . . .
+               *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; . . .
+               . . .
+             }
+          and compare assembler result with the result of another variant:
+             { extern int *A, *B;
+               int *a = A, *b = B;
+               . . .
+               *a++ = *b++; *a++ = *b++; *a++ = *b++; *a++ = *b++; . . .
+               . . .
+             }
+          I want the first result to be the same as the second.  */
+ #if 0
+
            /* This is the same as calling equiv_constant; it is duplicated
               here for speed.  */
            if (REGNO_QTY_VALID_P (REGNO (arg))
                && qty_const[reg_qty[REGNO (arg)]] != 0
                && GET_CODE (qty_const[reg_qty[REGNO (arg)]]) != REG
                && GET_CODE (qty_const[reg_qty[REGNO (arg)]]) != PLUS)
              const_arg
                = gen_lowpart_if_possible (GET_MODE (arg),
                                           qty_const[reg_qty[REGNO (arg)]]);
+ #endif /* 0  */
+
            break;

          case CONST:
          case CONST_INT:
          case SYMBOL_REF:
          case LABEL_REF:
          case CONST_DOUBLE:
            const_arg = arg;


    Probably, hear instead of `#if 0 ' a check of some machine-depended
macro should be used. However, this problem might be a general one.

                        Dmitry K. Butskoy,
                        Saint-Petersburg State Technical University,
                        St. Petersburg, Russia.

                        <buc@stu.spb.su>
Technical Details
Message-ID: <AAAd6nmmf3@stu.spb.su>
Path: arc1-ca.pugleaf.net!unknown!not-for-mail

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 113d02,fb878d25557e212b,start
X-Google-Attributes: gid113d02,public
From: buc@stu.spb.SU
Subject: GCC patch #3
Date: 1995/12/05
Message-ID: <AAAd6nmmf3@stu.spb.su>
X-Deja-AN: 120945680
distribution: gnu
sender: daemon@cis.ohio-state.edu
organization: State Technical University of St. Petersburg
newsgroups: gnu.gcc.bug