Shop OBEX P1 Docs P2 Docs Learn Events
cogc to big? — Parallax Forums

cogc to big?

dnalordnalor Posts: 223
edited 2012-08-14 12:59 in Propeller 1
What message will appear if COGC is too large?
I have some strange message:

(alfatdriver.cog+0x5c8): undefined reference to `_udwFileRead.constprop.0_ret'

collect2: ld returned 1 exit status

Done. Build Failed!

When I removed a few lines in this function, then the error message is gone.
Code size in the map file is then 0x618.

Comments

  • jazzedjazzed Posts: 11,803
    edited 2012-08-04 23:40
    dnalor wrote: »
    What message will appear if COGC is too large?

    It should be a message like:
    c:/propgcc/bin/../lib/gcc/propeller-elf/4.6.1/../../../../propeller-elf/bin/ld.exe: region `cog' overflowed by 24596 bytes
  • dnalordnalor Posts: 223
    edited 2012-08-05 03:47
    It should be a message like:
    c:/propgcc/bin/../lib/gcc/propeller-elf/4.6.1/../../../../propeller-elf/bin/ld.exe: region `cog' overflowed by 24596 bytes

    Something like that I would have expected.

    After sleeping a few hours, I see now a bug in the code.
    If you program an infinite loop, the rest of the code is simply trimmed. And then the error message makes sense.

    But that's one reason why I do not like gcc. Without optimization the code is useless big, with optimization the code is no longer that what you have written down.
    The volatile keyword, for example, I did not know before the first use of gcc.
  • Heater.Heater. Posts: 21,230
    edited 2012-08-05 04:08
    That is not the fault of GCC, pretty much all optimizing C, or other language, compilers will do that.
    If you think about it a bit it all makes sense and you will like it.
    If the result of a code sequence is unused in your program it makes sense for the optimizer to throw that sequence away. That can include entire function calls and the called functions.
    If a code sequence is obviously an infinite loop there is no point including the code that comes after it.
    If you have functions that are never called why put them in the binary?
    And so on.

    As for "volatile" if your code sets a variable that is never read by any other part of the source why would the compiler want to keep the code that set's that variable? As far as the compiler knows it is useless. Unless you tell it otherwise.

    Finay "volatile" is not a GCC thing. It is part of the C language.
  • dnalordnalor Posts: 223
    edited 2012-08-05 06:45
    Finay "volatile" is not a GCC thing. It is part of the C language.
    I know that.
    I've never learned and understood what it means and with the Renesas M16 I've also never used it and did not have a colleague who has ever used it. With the PIC24 and MPLAB-C, we have then learned what it means and that it is apparently necessary. But on a system with interrupts or even with multiple cores and shared memory area, it is perfectly clear that any global variable is volatile automatically.
    That is not the fault of GCC, pretty much all optimizing C, or other language, compilers will do that.
    If you think about it a bit it all makes sense and you will like it.
    If the result of a code sequence is unused in your program it makes sense for the optimizer to throw that sequence away. That can include entire function calls and the called functions.
    If a code sequence is obviously an infinite loop there is no point including the code that comes after it.
    If you have functions that are never called why put them in the binary?
    And so on.

    As for "volatile" if your code sets a variable that is never read by any other part of the source why would the compiler want to keep the code that set's that variable? As far as the compiler knows it is useless. Unless you tell it otherwise.

    I disagree. If I do not need the code, then I do not write it or I use conditional compilation. And what I write, the compiler should simply translate.
    If I write:
    while(globalVar);
    

    Then I do not want this:
    r0 = globalVar;
    while(r0);
    

    And if I write:
    while(localVar)
    {
        Do();
    };
    

    instead of:
    while(localVar)
    {
        Do();
        var--;
    };
    

    then it is my fault and compiler may throw a warning but never ever cut my code.
    A Compiler never should try to be too intelligent.
    And Cutting unused (library) functions is not task of the compiler, but the (smart-)linker.
  • evanhevanh Posts: 16,109
    edited 2012-08-05 07:25
    Heater is right, it's a C thing and maybe even more a compiler thing than C per se. Not GCC specifically. I'm feeling the C hate coming on here ... :P

    Optimising -- It exploits the tendency of coding to be extremely single threaded. So, if you know that there is concurrent interfacing then telling (volatile) the compiler about it will allow the compiler to make sure the specified memory references are in-order accessed as per the source code.

    With regard to globals, I kind of agree in one sense but then we're ending up hand optimising most accesses of globals which I have to admit I do do just to be sure.
  • Heater.Heater. Posts: 21,230
    edited 2012-08-05 23:34
    dnalor,
    ...on a system with interrupts or even with multiple cores and shared memory area, it is perfectly clear that any global variable is volatile automatically.
    This is not true. The default assumption of the language is that all variables, global or otherwise, are under the control of the program being compiled, i.e. not volatile. The "volatile" keyword tells the compiler that this is not so, that the variable may be read or written by some process, hardware or software, that the compiler cannot be aware of by processing that source code. Typically a processor register altered by hardware.

    Imagine a global variable, "int A", that you write to but never read in your program. Then the compiler can rightly assume the value written is never used and all code that does the writing can safely be removed. Now "A" might actually be a processor register, in which case the hardware uses the values written to it and "volatile" says "do not optimize those writes away".
    I disagree. If I do not need the code, then I do not write it or I use conditional compilation. And what I write, the compiler should simply translate.
    I sort know what you are driving at but I'm sure you don't mean it:) If you have "A = 2 * M_PI;" in your code I bet you are happy that the compiler calculates "2 * M_PI" at compile time and uses the resulting constant to load "A" instead of inserting the code to do a long winded multiply.
    Then I do not want this:
    r0 = globalVar;
    while(r0);
    
    Perhaps not a good example but I'm sure you do want the compiler to do that. i.e. keep things in registers as much as possible for fast execution. The alternative is that everything is kept in RAM all the time and has to be loaded and stored repeatedly resulting in larger slower code.

    If that is really what you want the turn off all optimizations "-O0".
    A Compiler never should try to be too intelligent.
    Sure it should. See above.
    And Cutting unused (library) functions is not task of the compiler, but the (smart-)linker.

    Yes a linker should do that, BUT if you think about it that is not always possible. For example in code like:
    while (1)
    {
        do_something();
    }
    printf("Done\n");
    
    Clearly the compiler might work out that "printf" can never be callled and so remove the call to it. The linker may then not include "printf" from the library.

    BUT linker cannot know that this "printf" is unused. Unless it is really smart and can analyse the code, At which point it is doing what the compiler does so why not let the compiler do it. Besides linkers have to work for many languages not just C so that kind of analysis does not belong in the linker.
  • pedwardpedward Posts: 1,642
    edited 2012-08-06 18:15
    Something you are not accustomed to is that GCC has a very aggressive static code analyzer. There are a lot of players using GCC and contributing changes back to it. GCC isn't on par with the highly customized compilers available from chip vendors, such as Intel, but it is a lot better than some of the simpler compilers that vendors have ported for their chip architectures. Renesas used HEW as their compiler last I had anything to do with them. HEW isn't based on GCC or any open source code AFAIK, so it probably has much less aggressive optimization. PIC on the other hand probably leverages GCC or LCC, which explains your need to learn about volatile.
  • dnalordnalor Posts: 223
    edited 2012-08-07 11:56
    Yes Microchips C Compiler for PIC24 is some gcc-clone (http://ww1.microchip.com/downloads/en/DeviceDoc/MPLABC30_v331_README.html#Limitations) and as far I know the Renesas M16C compiler (nc30) is not based on a opensource compiler.
    And it is very good to have a compiler that produces predictabel code. Then C is exactly what it should be, a good 'macro language' for assembler.
    With gcc you get often bad surprises. But I do not want to complain. It is definitely the best solution that exists so far for the propeller.

    Is there any way to change optimisation for cogc files in SimpleIDE ? It seems to be fixed to Os.
    Wich optimisation levels/options are available ?
  • Heater.Heater. Posts: 21,230
    edited 2012-08-07 12:19
    GCC has optimization levels -O0 -O1 -O3 etc. If you read the manual very hard you can figure out what they mean. Alternatively individual optimization techniques can be enabled/disabled with other obscure switches.

    My feeling is that one cannot complain that the code is too big to fit in COG and at the same time complain that the optimizer is working too well. If niether of those are acceptable just use PASM.

    Given the space constraints of the Prop -Os is pretty much essential.
  • Heater.Heater. Posts: 21,230
    edited 2012-08-07 12:22
    Oh yeah, even if C is a low level "high level" language I disagree that it was ever supposed to be a macro processor for assembler. It offers so much more.
  • dnalordnalor Posts: 223
    edited 2012-08-07 12:53
    My feeling is that one cannot complain that the code is too big to fit in COG and at the same time complain that the optimizer is working too well. If niether of those are acceptable just use PASM.

    You heat up quite fast, Heater !???
    I did not complain. I had a message that I did not understand. My suspicion was that it was because of size.

    But in my opinion, gcc is too aggressive and it's not my preferred compiler if there is another.
    You do not have to agree !
    GCC has optimization levels -O0 -O1 -O3 etc. If you read the manual very hard you can figure out what they mean. Alternatively individual optimization techniques can be enabled/disabled with other obscure switches.
    But not for cogc files or do I miss something ?

    btw. the correct message is: ../propgcc/bin/../lib/gcc/propeller-elf/4.6.1/../../../../propeller-elf/bin/ld.exe: address 0x7e8 of a.out section `alfatdriver.cog' is not within region `coguser'
  • jazzedjazzed Posts: 11,803
    edited 2012-08-07 13:00
    Optimizations work regardless of the memory model.

    @dnalor, If you prefer another compiler, then I suggest you start using it.
    298 x 255 - 17K
  • Heater.Heater. Posts: 21,230
    edited 2012-08-07 13:09
    Dnalor,
    Sorry if I seem to be heating up. I just don't get the logic of what you are saying. If GCC optimizations are too agressive then sure use some other less aggressive compiler. But then quite likely your code will not fit in COG again.
    So what's the point? GCC is a really unagressive puppy at -O0 and anyway we have no other C compiler that will generate native PASM to run in COG.
    OK perhaps SimpleIDE should have a means to set whatever optimization and other options we like. Just not sure it it would be very useful.

    As we started with a question about the meaning of a compiler error message, I might agree that sometimes it is not clear what the problem is. Over time you get used to most of them. Error messages from C++ are a thousand times worse.
  • evanhevanh Posts: 16,109
    edited 2012-08-08 05:20
    dnalor wrote: »
    But in my opinion, gcc is too aggressive and it's not my preferred compiler if there is another.

    That there is very much a complaint. And specifically a complaint about GCC. Posts #3 and #5 are complaints too.


    I think what is really the problem here is not so much what the compiler is doing but the lack of immediate extended help on what the meaning of the error is.


    PS: When I said it's "maybe even more a compiler thing than C per se" I meant all compiled code and languages. Not just C. This is one distinction between a compiler and an interpreter or assembler. Compiling guarantees the binary is not the same as the source.
  • dnalordnalor Posts: 223
    edited 2012-08-09 12:24
    Complaints ?
    These are statements.
    I think what is really the problem here is not so much what the compiler is doing but the lack of immediate extended help on what the meaning of the error is.
    A meaningful error message would help.
    I just don't get the logic of what you are saying.
    The compiler should optimise the code in such way, that it is predictable and trustable and I want full control about what compiler does. If the compiler cuts the code without warning, then it is not acceptable.

    @jazzed
    The settings in SimpleIde do work only for the main file not the cogc files. Cogc files are always -Os.
    propeller-elf-gcc.exe -r -Os -mcog -o alfatdriver.cog -xc alfatdriver.cogc
    propeller-elf-objcopy --localize-text --rename-section .text=alfatdriver.cog alfatdriver.cog
    propeller-elf-gcc.exe -o a.out -O0 -mlmm -I . -m32bit-doubles -fno-exceptions -Dprintf=__simple_printf alfatdriver.cog soundmodul_var.h alfatdriver.h typedefs.h Soundmodul.c
    propeller-elf-objdump -h a.out
    Done. Build Succeeded!
    
    If you prefer another compiler, then I suggest you start using it.
    That is now do or die but shut up, your opinion does not matter. Right ? Is this your opinion or parallax'.
  • jazzedjazzed Posts: 11,803
    edited 2012-08-09 13:03
    dnalor wrote: »
    The settings in SimpleIde do work only for the main file not the cogc files. Cogc files are always -Os.
    Ok, I see now. The optimization works for the main file but not for the .cogc file. All I can do is make the optimization global. For better control, one would need to use make or copy the SimpleIDE output to a batch file and modify/use that.
    dnalor wrote: »
    That is now do or die but shut up, your opinion does not matter. Right ? Is this your opinion or parallax'.
    Purely my opinion. I read your statement regarding another compiler thinking that you had one in mind and prefer using it. That's all.
  • Dave HeinDave Hein Posts: 6,347
    edited 2012-08-09 15:15
    On the issue of volatile globals, it seems like GCC always treats global variables as volatile. At least that's what I see in the generated assembly for all optimization levels. The place where you can get in trouble is if you use a local pointer to reference a global variable. The local pointer variable needs to be declare as volatile, or the optimizer will just check the value once.
  • evanhevanh Posts: 16,109
    edited 2012-08-10 05:30
    Dave Hein wrote: »
    On the issue of volatile globals, it seems like GCC always treats global variables as volatile.

    Cool, I guess my hand crafted optimising wasn't worthless after all.
  • dnalordnalor Posts: 223
    edited 2012-08-10 08:59
    jazzed wrote: »
    All I can do is make the optimization global.
    That's maybe also wrong.
    jazzed wrote: »
    For better control, one would need to use make or copy the SimpleIDE output to a batch file and modify/use that.
    Copy to batch. Ah, that's a good suggestion! Thank you.
    For that it would be nice to have one (or more) user button(s) or entry(s) in Tools menu, which is/are saved in project file. Then one could start batchfile(s) with a click.
    jazzed wrote: »
    I read your statement regarding another compiler thinking that you had one in mind and prefer using it. That's all.
    No. Propgcc is the best solution so far. My experience with gcc were just not that good so far. But you guys did a much better job than imagecraft with their compiler. They have stopped halfway and wondered why no one wants to have their (propeller) compiler.
  • dnalordnalor Posts: 223
    edited 2012-08-12 03:18
    Optimisation global:
    If I do rightclick show assembly on a cogc file it takes optimisation from project options (there it seems to be global).
    Build do always -Os (there it is not global).
    I think it should be global in both cases or not global in both cases.
  • jazzedjazzed Posts: 11,803
    edited 2012-08-13 21:09
    dnalor wrote: »
    Optimisation global:
    If I do rightclick show assembly on a cogc file it takes optimisation from project options (there it seems to be global).
    Build do always -Os (there it is not global).
    I think it should be global in both cases or not global in both cases.

    Thanks for pointing this out. Some consistency is at least expected. I'm still searching for a good solution. Make a .bat or .sh is probably a good idea, but I would have to capture the sequence and allow a build by batch. Any other ideas on this?
  • dnalordnalor Posts: 223
    edited 2012-08-14 11:32
    An experienced programmer would expect a breakdown in the project manager for h, c, cogc and ecogc. There you could change the settings for each (cog-)file per right-click and a small popup or something similar.
    http://forums.parallax.com/showthread.php?140797-Is-this-possible-in-PropGCC&p=1106348&viewfull=1#post1106348

    But I think you want keep things in SimpleIde as beginner friendly as possible. So fixed optimisation -Os for cogc and other files with project options is maybe the best (like you did it).
    Copy from output pane to batchfile "by hand" is not too difficult. But starting this batchfile should be possible with click on a button (see post #20).
  • Dave HeinDave Hein Posts: 6,347
    edited 2012-08-14 12:00
    You can insert a "#pragma GCC optimize ("Os")" in the cogc source file to force Os optimization. This will override the optimization setting that is used on the command line. You can also use "#pragma GCC push_options" to save the command-line options, and then "#pragma GCC pop_options" to restore them. This would allow you to change the optimization for only part of a file.
  • dnalordnalor Posts: 223
    edited 2012-08-14 12:19
    Dave Hein wrote: »
    You can insert a "#pragma GCC optimize ("Os")" in the cogc source file to force Os optimization. This will override the optimization setting that is used on the command line. You can also use "#pragma GCC push_options" to save the command-line options, and then "#pragma GCC pop_options" to restore them. This would allow you to change the optimization for only part of a file.

    Aha. Then all ways are open.

    If you know what you have to look after, then you sometimes find something:
    http://gcc.gnu.org/wiki/FunctionSpecificOpt
  • jazzedjazzed Posts: 11,803
    edited 2012-08-14 12:59
    Great. Thanks Dave. I didn't think about pragma. At minimum I'll make the build/asm list choice consistent and document pragmas in the user guide.
Sign In or Register to comment.