The following two literal initializer data should both be considered static 
const data references:

 char s[5] = "abcde";
 char t[5] = {'a','b','c','d','e'};

 the memory reference to "abcde" should be marked readonly, not frame-relative 
(as it isn't),
 as otherwise it's impossible to properly identify "static const data" memory 
references at the
tree/rtl level as may be required for target specific code/data 
generation/optimization.

The following shows the problem (as well as a missed optimization associated 
with potentially
being able to access the initializer data directly, as opposed to accessesing 
the frame-relative
variable data string/array after being copied if never modifed; and an 
inappropriate inline of
function foo() which should not have likely been inlined given it's size, and 
note that bar being
identical wan't inlined, which is correct):

volatile char v;

void foo ( void )
{
  char x[5] = "abcde";
  
  v = x[v];
}

void bar ( void )
{
  char y[5] = {'a','b','c','d','e'};
  
  v = y[v];
}

int main ( void )
{
  char x[5] = "abcde"; // Initializer string not marked READONLY static const.
  
  char y[5] = {'a','b','c','d','e'}; // Although char arrary is correctly.
      
  v = x[v];
  
  v = y[v];
  
  foo();
  
  bar();
  
  return 0;
}

resulting code:

volatile char v;

void foo ( void )
{
  c6:   cf 93           push    r28
  c8:   df 93           push    r29
  ca:   cd b7           in      r28, 0x3d       ; 61
  cc:   de b7           in      r29, 0x3e       ; 62
  ce:   25 97           sbiw    r28, 0x05       ; 5
  d0:   0f b6           in      r0, 0x3f        ; 63
  d2:   f8 94           cli
  d4:   de bf           out     0x3e, r29       ; 62
  d6:   0f be           out     0x3f, r0        ; 63
  d8:   cd bf           out     0x3d, r28       ; 61
  
  char x[5] = "abcde";
  da:   de 01           movw    r26, r28
  dc:   11 96           adiw    r26, 0x01       ; 1
  de:   e0 e0           ldi     r30, 0x00       ; 0
  e0:   f1 e0           ldi     r31, 0x01       ; 1
  e2:   85 e0           ldi     r24, 0x05       ; 5
  e4:   01 90           ld      r0, Z+
  e6:   0d 92           st      X+, r0
  e8:   81 50           subi    r24, 0x01       ; 1
  ea:   e1 f7           brne    .-8             ; 0xe4 <foo+0x1e>
  
  v = x[v];
  ec:   80 91 10 01     lds     r24, 0x0110
  f0:   fe 01           movw    r30, r28
  f2:   e8 0f           add     r30, r24
  f4:   f1 1d           adc     r31, r1
  f6:   81 81           ldd     r24, Z+1        ; 0x01
  f8:   80 93 10 01     sts     0x0110, r24
  
  fc:   25 96           adiw    r28, 0x05       ; 5
  fe:   0f b6           in      r0, 0x3f        ; 63
 100:   f8 94           cli
 102:   de bf           out     0x3e, r29       ; 62
 104:   0f be           out     0x3f, r0        ; 63
 106:   cd bf           out     0x3d, r28       ; 61
 108:   df 91           pop     r29
 10a:   cf 91           pop     r28
 10c:   08 95           ret

0000010e <bar>:
}

void bar ( void )
{
 10e:   cf 93           push    r28
 110:   df 93           push    r29
 112:   cd b7           in      r28, 0x3d       ; 61
 114:   de b7           in      r29, 0x3e       ; 62
 116:   25 97           sbiw    r28, 0x05       ; 5
 118:   0f b6           in      r0, 0x3f        ; 63
 11a:   f8 94           cli
 11c:   de bf           out     0x3e, r29       ; 62
 11e:   0f be           out     0x3f, r0        ; 63
 120:   cd bf           out     0x3d, r28       ; 61
 
  char y[5] = {'a','b','c','d','e'};
 122:   de 01           movw    r26, r28
 124:   11 96           adiw    r26, 0x01       ; 1
 126:   e6 e0           ldi     r30, 0x06       ; 6
 128:   f1 e0           ldi     r31, 0x01       ; 1
 12a:   85 e0           ldi     r24, 0x05       ; 5
 12c:   04 90           lpm     r0, Z
 12e:   0d 92           st      X+, r0
 130:   81 50           subi    r24, 0x01       ; 1
 132:   e1 f7           brne    .-8             ; 0x12c <bar+0x1e>
  
  v = y[v];
 134:   80 91 10 01     lds     r24, 0x0110
 138:   fe 01           movw    r30, r28
 13a:   e8 0f           add     r30, r24
 13c:   f1 1d           adc     r31, r1
 13e:   81 81           ldd     r24, Z+1        ; 0x01
 140:   80 93 10 01     sts     0x0110, r24
 
 144:   25 96           adiw    r28, 0x05       ; 5
 146:   0f b6           in      r0, 0x3f        ; 63
 148:   f8 94           cli
 14a:   de bf           out     0x3e, r29       ; 62
 14c:   0f be           out     0x3f, r0        ; 63
 14e:   cd bf           out     0x3d, r28       ; 61
 150:   df 91           pop     r29
 152:   cf 91           pop     r28
 154:   08 95           ret

00000156 <main>:
}

int main ( void )
{
 156:   c0 ef           ldi     r28, 0xF0       ; 240
 158:   d0 e1           ldi     r29, 0x10       ; 16
 15a:   de bf           out     0x3e, r29       ; 62
 15c:   cd bf           out     0x3d, r28       ; 61
 
  char x[5] = "abcde"; // Initializer string not marked READONLY static const.
 15e:   de 01           movw    r26, r28
 160:   11 96           adiw    r26, 0x01       ; 1
 162:   e0 e0           ldi     r30, 0x00       ; 0
 164:   f1 e0           ldi     r31, 0x01       ; 1
 166:   85 e0           ldi     r24, 0x05       ; 5
 168:   01 90           ld      r0, Z+
 16a:   0d 92           st      X+, r0
 16c:   81 50           subi    r24, 0x01       ; 1
 16e:   e1 f7           brne    .-8             ; 0x168 <main+0x12>
  
  char y[5] = {'a','b','c','d','e'}; // Although char arrary is correctly.
 170:   de 01           movw    r26, r28
 172:   16 96           adiw    r26, 0x06       ; 6
 174:   eb e0           ldi     r30, 0x0B       ; 11
 176:   f1 e0           ldi     r31, 0x01       ; 1
 178:   85 e0           ldi     r24, 0x05       ; 5
 17a:   04 90           lpm     r0, Z
 17c:   0d 92           st      X+, r0
 17e:   81 50           subi    r24, 0x01       ; 1
 180:   e1 f7           brne    .-8             ; 0x17a <main+0x24>
      
  v = x[v];
 182:   80 91 10 01     lds     r24, 0x0110
 186:   fe 01           movw    r30, r28
 188:   e8 0f           add     r30, r24
 18a:   f1 1d           adc     r31, r1
 18c:   81 81           ldd     r24, Z+1        ; 0x01
 18e:   80 93 10 01     sts     0x0110, r24
  
  v = y[v];
 192:   80 91 10 01     lds     r24, 0x0110
 196:   fe 01           movw    r30, r28
 198:   e8 0f           add     r30, r24
 19a:   f1 1d           adc     r31, r1
 19c:   86 81           ldd     r24, Z+6        ; 0x06
 19e:   80 93 10 01     sts     0x0110, r24
 
  foo(); char x[5] = "abcde";
 1a2:   de 01           movw    r26, r28
 1a4:   1b 96           adiw    r26, 0x0b       ; 11
 1a6:   e0 e0           ldi     r30, 0x00       ; 0
 1a8:   f1 e0           ldi     r31, 0x01       ; 1
 1aa:   85 e0           ldi     r24, 0x05       ; 5
 1ac:   01 90           ld      r0, Z+
 1ae:   0d 92           st      X+, r0
 1b0:   81 50           subi    r24, 0x01       ; 1
 1b2:   e1 f7           brne    .-8             ; 0x1ac <main+0x56>
 
  foo(); v = x[v];
 1b4:   80 91 10 01     lds     r24, 0x0110
 1b8:   fe 01           movw    r30, r28
 1ba:   e8 0f           add     r30, r24
 1bc:   f1 1d           adc     r31, r1
 1be:   83 85           ldd     r24, Z+11       ; 0x0b
 1c0:   80 93 10 01     sts     0x0110, r24
  
  bar();
 1c4:   0e 94 87 00     call    0x10e <bar>
  
  return 0;
}
 1c8:   80 e0           ldi     r24, 0x00       ; 0
 1ca:   90 e0           ldi     r25, 0x00       ; 0
 1cc:   0c 94 e8 00     jmp     0x1d0 <_exit>

000001d0 <_exit>:
 1d0:   ff cf           rjmp    .-2             ; 0x1d0 <_exit>

from gimple:

;; Function main (main)

main ()
{
  static char C.3[5] = {97, 98, 99, 100, 101}; // should probably be "static 
const char"
  volatile char v.4;
  int D.1152;
  char D.1153;
  volatile char v.5;
  int D.1155;
  char D.1156;
  int D.1157;

  {
    char x[5];
    char y[5];

    x = "abcde";   // should have been separatly declared "static const char" 
initilizer.
    y = C.3;
    v.4 = v;
    D.1152 = (int) v.4;
    D.1153 = x[D.1152];
    v = D.1153;
    v.5 = v;
    D.1155 = (int) v.5;
    D.1156 = y[D.1155];
    v = D.1156;
    {
      {
        volatile char v.0;
        int D.1185;
        char D.1186;
        char x[5];

        x = "abcde";
        v.0 = v;
        D.1185 = (int) v.0;
        D.1186 = x[D.1185];
        v = D.1186;
      }
    }
    (void) 0;
    bar ();
    D.1157 = 0;
    return D.1157;
  }
  D.1157 = 0;
  return D.1157;
}

resulting tree/rtl:

showing frame-relative reference to "abcde" initializing data which is wrong:

(insn 12 11 13 1 (set (reg:HI 44)
        (symbol_ref/f:HI ("*.LC0") [flags 0x2] <string_cst 0x160b840>)) -1 (nil)
    (nil))

showing readonly reference to {'a','b','c','d','e') initializing data which is 
correct:

(insn 23 36 24 3 (set (reg:QI 42 [ v.0 ])
        (mem/v/i:QI (symbol_ref:HI ("v") <var_decl 0x16791b0 v>) [0 v+0 S1 
A8])) -1 (nil)
    (nil))

-- 
           Summary:  initilizing string litteral data improperly maked
                    frame-relative, should be readonly static const.
           Product: gcc
           Version: 4.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P2
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: schlie at comcast dot net
                CC: gcc-bugs at gcc dot gnu dot org
 GCC build triplet: ppc-apple-darwin7.8
  GCC host triplet: ppc-apple-darwin7.8
GCC target triplet: ppc-apple-darwin7.8 / avr-none-none


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=21018

Reply via email to