When using C99, does avr-gcc optimize code when it sees the restrict type qualifier?
C99 restrict Type qualifier
Personally I haven't seen any real-world code using the 'restrict' type qualifier, yet. But GCC, in general, implements a lot of C99, so I'm sure it knows how to deal with it. If you're looking for some particular type of optimization, then the best thing to do is to experiment to see if the compiler is doing what you expect it to do.
Other operating system's libraries at least started using "restrict"
some time ago. I guess we should start in avr-libc as well, at least
for non-asm code. Well, perhaps some of the asm code could even be
replaced by C code then...
I tried some examples of code that should be optimized when restrict is used but the assemble code doesn't change.
void foo ( uint8_t * a1, uint8_t * a2) { uint8_t i; for ( i = 0; i < 10; i++ ) a1[i] += a2[i]; a1 = a2; //-OK, without restrict } void bar ( uint8_t *restrict a1, uint8_t *restrict a2) { uint8_t i; for ( i = 0; i < 10; i++ ) a1[i] += a2[i]; a1 = a2; //- UnDefined }
22 /* prologue: frame size=0 */ 23 /* prologue end (size=0) */ 24 .LVL0: 25 0000 DC01 movw r26,r24 26 0002 20E0 ldi r18,lo8(0) 27 0004 30E0 ldi r19,hi8(0) 28 .L2: 29 .LM2: 30 0006 FB01 movw r30,r22 31 0008 E20F add r30,r18 32 000a F31F adc r31,r19 33 000c 8C91 ld r24,X 34 .LVL1: 35 000e 9081 ld r25,Z 36 0010 890F add r24,r25 37 0012 8D93 st X+,r24 38 0014 2F5F subi r18,lo8(-(1)) 39 0016 3F4F sbci r19,hi8(-(1)) 40 .LM3: 41 0018 2A30 cpi r18,10 42 001a 3105 cpc r19,__zero_reg__ 43 001c 01F4 brne .L2 44 /* epilogue: frame size=0 */ 45 001e 0895 ret 46 /* epilogue end (size=1) */ 47 /* function foo size 16 (15)*/
Other operating system's libraries at least started using "restrict"
some time ago. I guess we should start in avr-libc as well, at least
for non-asm code. Well, perhaps some of the asm code could even be
replaced by C code then...
Then we need to make sure that our policy is to build to the C99 standard.
I'd also rather not change asm code to C, because with the asm code, it doesn't change according to the optimization setting and compiler version. If anything I would rather go from C to asm, but I know that it would be difficult for some functions like printf, scanf, qsort, etc.
I was looking at the opposite problem: the deliberate use of type-punned pointers (which have an implicit restrict). The discussion indicated that the gcc people were trying to start implementing optimisations.
I found that the latest version of gcc gave me a code size 2 bytes smaller when I used (with -0s) -fno-strict-aliaising, which for an optimisation is a change in the wrong direction, but indicates that something is changing. As a consequence, I am now using -fno-strict-aliasing, in the expectation that a new version of gcc is coming which will have optimisations for (implicit or explicit) 'restrict'.
OK, this is a really old thread. But the optimizer and support of GCC has increased.
So I tried the following test program:
#include <avr/io.h> #define VECTOR_SIZE 4U void vectorCopy1(uint8_t *a, uint8_t *b, uint8_t *c) { uint8_t i; for (i = 0U; i < VECTOR_SIZE; ++i) { b[i] = a[i]-1U; c[i] = a[i]+1U; } } void vectorCopy2(uint8_t *restrict a, uint8_t *restrict b, uint8_t *restrict c) { uint8_t i; for (i = 0U; i < VECTOR_SIZE; ++i) { b[i] = a[i]-1U; c[i] = a[i]+1U; } } int main(void) { uint8_t x[VECTOR_SIZE] = {1U,2U,3U,4U}; uint8_t y[VECTOR_SIZE]; uint8_t z[VECTOR_SIZE]; vectorCopy1(x, y, z); vectorCopy2(x, y, z); }
Looking in the assembler code, I found function vectorCopy2 smaller than vectorCopy1.