Possible compiler bug?
Jack Buffington
Posts: 115
I originally posted this in the regular propeller forum since I thought that it had nothing to do with the C compiler but now I see that it does.
I have a .cogc file that is sharing a variable with HUB RAM, or at least I want it to be shared. In my main cog, I am declaring the variable like this:
volatile int iris = 1234;
The sum total of my .cogc file looks like this:
The assembly listing that I get looks like this:
As you can see, "iris" is never written to HUB RAM nor is it AND'ed with 3. I have found that I can get it to compile if I set the compiler to "-O0 None" but then it produces some pretty inefficient code and even worse, it causes the rest of my program not to fit into HUB RAM. It seems like it shouldn't optimize out a write to HUB RAM ever. Does anyone have ideas about how to make this work without dropping to inline assembly code? I'm making it work with the addition of a waitcnt for now but I would rather not do that.
If you were following this on the other forum, the confusion that I was having there was that if I stick in a waitcnt command, the code compiles properly but only works if I give it enough time to run everything else. I had noticed that it ran if I put waitcnt in but didn't work if I left it out so I was assuming that it had something to do with how much delay I was giving it.
I have a .cogc file that is sharing a variable with HUB RAM, or at least I want it to be shared. In my main cog, I am declaring the variable like this:
volatile int iris = 1234;
The sum total of my .cogc file looks like this:
#include <propeller.h>extern unsigned int iris; _NATIVE void main () { while(1) { iris = INA & 0b11; } }
The assembly listing that I get looks like this:
1 .text 2 .Ltext0 3 .balign 4 4 .global _main 5 .global _main_ret 6 _main 7 .LFB0 8 .file 1 "encoder.cogc" 1:encoder.cogc **** #include <propeller.h> 2:encoder.cogc **** extern unsigned int iris; 3:encoder.cogc **** 4:encoder.cogc **** _NATIVE 5:encoder.cogc **** void main () 6:encoder.cogc **** { 9 .loc 1 6 0 10 .L2 7:encoder.cogc **** while(1) 8:encoder.cogc **** { 9:encoder.cogc **** iris = INA & 0b11; 11 .loc 1 9 0 discriminator 1 12 0000 0000BCA0 mov r7, INA 13 0004 00007C5C jmp #.L2 14 .LFE0 42 .Letext0 43 .file 2 "c:\\propgcc\\bin\\../lib/gcc/propeller-elf/4.6.1/../../../../propeller-elf/include/cog.h"
As you can see, "iris" is never written to HUB RAM nor is it AND'ed with 3. I have found that I can get it to compile if I set the compiler to "-O0 None" but then it produces some pretty inefficient code and even worse, it causes the rest of my program not to fit into HUB RAM. It seems like it shouldn't optimize out a write to HUB RAM ever. Does anyone have ideas about how to make this work without dropping to inline assembly code? I'm making it work with the addition of a waitcnt for now but I would rather not do that.
If you were following this on the other forum, the confusion that I was having there was that if I stick in a waitcnt command, the code compiles properly but only works if I give it enough time to run everything else. I had noticed that it ran if I put waitcnt in but didn't work if I left it out so I was assuming that it had something to do with how much delay I was giving it.
Comments
In short, it prevents the compiler from optimizing the variable away. The compiler can be a little too aggressive sometimes, and since your code didn't actually use the assignment, it gets optimized away.
The problem is that you were declaring a different type with your original extern declaration, and that type wasn't volatile (and was unsigned instead of signed, but that's another issue). All the extern keyword does is prevent the immediate allocation of memory for a variable, leaving it unfulfilled until link time.
What SRLM said.
The best way to declare variables that are shared between multiple modules (even if one is a .cogc and another is a .c file) is to declare them in a separate file (say, iris.h) and include that file in all the modules where you use the variable.
Of course, you can (should!) remove the "extern volatile int iris" declaration from your .cogc module when you #include "iris.h".
This will prevent conflicts e.g. between unsigned and signed integers, and other potential problems: whenever you want to change the declaration you only have to do it in one place: iris.h.
The "extern" keyword isn't really necessary except in cases where you want your global variable initialized to something other than 0. In that case you'll have to do something like this:
===Jac