Re: [Mspgcc-users] Unused functions occupying unnecessary memory
Von: Grant Edwards Gesendet am: 23 Jun 2010 18:01:14 I never got one. In theory, my frontend should capture stdout and stderr. And normally I see any output from compiler and/or linker. So I never thought that I was missing the -Wl prefix. That's bizarre. Indeed. I just tested it again from commandline, enabling the commandline echo, so I can see what is called. Here's the output: c:/Programme/msp430/mspgcc_0812/bin/msp430-gcc -mmcu=msp430x5436 -Wl,--gc-sections -nonsense --nonsense -gc-sections --gc-sections obj/Linktest.o obj/dummy.o -o lib/Linktest.elf No output whatsoever from ld, except for the elf file. If there are linking errors, I get them, of course. Looks like gcc is not complaining about unknown options when called for the linker stage. It seems to just ignore all except those directed to the linker. If I add a nonsense option to the CPFLAGS, GCC will complain. I don't understand why the -gc-sections flag is needed to activate a functionality I consider the default behaviour of a linker. I've been doing embedded development for 25+ years and I don't ever remember seeing a linker where that was the default behavior. Well, I do it only for 5 years now (if you don't count the C64 as an embedded system even if todays MSPs are way more capable) I used quite a few for normal application development, however. On some systems, I KNOW that the linker did not just keep everything, and from an engineers view it is just logical. On most others, I just didn't care at all. (I seldom write superfluous code at all). Even on MSP, I usually only include object files into the project which are in use. The only exception is the current play-and-port project for the 5438, where I included all already ported sources from previous projects, even if not currently used. Maybe that is why my predecessor put all object files into a library and linked it, so unreferenced object files didn't get linked, while introducing that maybe even (later) referenced code wasn't linked. Yes, that's why libraries were invented: because linkers didn't discard unused object files. I always thought this was invented because it is easier to add one library to a project than hundreds of object files. And dynamically linking to a library is easier too. My mistake. The default case for gnu binutils ld and every other linker I've ever used is to keep all the object files you tell it to link regardless of whether they are referenced or not. For those who do not spend their time with working on ld or studying bookstores of documentation first before they can compile and link a simple 'hello world' (so 99% of all users), this information, while being useful and important, is practically invisible. Only if you know where to look (and that you have to look) you'll eventually find it. No wonder that todays software is so big and bloated. I just wonder how big the percentage of unused, unreachable code in typical programs is. On PCs, this might be a don't care, but on embedded systems, I consider it of much interest for a large percentage of users. Well, now that everything is (more or less) clear (except of the question why there is no warning for unknown options), we should close this thread, as it starts to stray off-topic. JMGross
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
Von: Grant Edwards Gesendet am: 22 Jun 2010 16:16:20 segments - = sections. I think I got the 'empty' by browsing the ld option description. Or i dedutcted it from your expression of discarded unused content. unused != empty right. Well, when all content has been discarded because being unused, it is empty. :) Second, it's '--gc-sections' not '-gc-sections' I tried both :) And both would have produced an error/warning using your posted makefile, which should have prompted you to try figure out what you were doing wrong rather than claiming the feature didn't work: I never got one. In theory, my frontend should capture stdout and stderr. And normally I see any output from compiler and/or linker. So I never thought that I was missing the -Wl prefix. I just tried agian with intentionally requesting an error message, yet there was none. Then I tried to call make from the windows 'DOS' console. Still no error message. Is it possible that it is pushed into an output streamthat is swallowed by the windows environment? Unlinkely, I know, as other warnings/errors come through That's the point. (or nearly, according to the GC manual, it is -Wl,x (which works) Right. Sorry about the typo. No problem, now that I was pointed into the right direction. I read the ld documentation and missted the fact that the compiler gets the options first, even if added to LDFLAGS. The ld documentation has no way of knowing what program you're passing LDFLAGS to in your Makefile. Now that I remember that ld is called through gcc, it's obvious. Most of the makefile setup was inherited from my predecessor and I guess he got most of it from the mspgcc templates. Nevertheless, I don't understand why foo() is added to the binary by the linker default, while it is not referenced and in its own object file. Because you didn't pass the --gc-sections flag to the linker to tell it to discard unreferenced sections. let me rearrange the statement: I don't understand why the -gc-sections flag is needed to activate a functionality I consider the default behaviour of a linker. I would understand that you'll need to tell the linker that you want to _keep_ unreferenced information, but not that it will by default keep everything (at least for object files and even completely unreferenced object files) while it does discard unused parts from a library. Maybe that is why my predecessor put all object files into a library and linked it, so unreferenced object files didn't get linked, while introducing that maybe even (later) referenced code wasn't linked. When I took over the projects, I had no way to ask him as he left the company. Since 1) is the default, binary files may be unnecessary large by default. Yes. And that's what I don't understand: why is the special case (keep it even if not referenced and therefore unreachable) is the default and the default case (keep only what's used) requires extra treatment. Anyway, now that I know that it is so, I can live with it. So while I'm sorry alarming you unnecessarily, I'm quite happy that I did, as I gained some valuable insights from this discussion. And maybe others did too. After all this is a compiler users mailing list and not a compiler programmers list. :) JMGross
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
One reason why keep it even if unreferenced may be the default even when optimizations are enabled is that these tools (binutils, gcc) are primarily used in environments that have far more capabilities, and couldn't care less if a few extra kilobytes are present in the image. If you work in Linux with dynamic libraries, which is the common case, it's easy to use dlopen to resolve symbols at runtime that are not referenced at link time, and invoke unreachable code that way. The simplest perspective is user provided it, so leave it alone. The user's supposed to know best; I don't want the software to be overly helpful unless I explicitly give it permission. Peter On Wed, Jun 23, 2010 at 10:07 AM, JMGross msp...@grossibaer.de wrote: Since 1) is the default, binary files may be unnecessary large by default. Yes. And that's what I don't understand: why is the special case (keep it even if not referenced and therefore unreachable) is the default and the default case (keep only what's used) requires extra treatment. Anyway, now that I know that it is so, I can live with it. So while I'm sorry alarming you unnecessarily, I'm quite happy that I did, as I gained some valuable insights from this discussion. And maybe others did too. After all this is a compiler users mailing list and not a compiler programmers list. :) JMGross -- ThinkGeek and WIRED's GeekDad team up for the Ultimate GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the lucky parental unit. See the prize list and enter to win: http://p.sf.net/sfu/thinkgeek-promo ___ Mspgcc-users mailing list Mspgcc-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mspgcc-users
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
- Ursprüngliche Nachricht - Von: Grant Edwards Gesendet am: 21 Jun 2010 16:54:37 If I understood the linker scripts correctly, the linker will put all .text and .text.* compiler segments into the linker text segment. After the unreferenced .text.* sections are discarded, the remaining ones will all be placed into the .text section in the output file. As I undestood you, the linker should do this for any (complete) object file anyway, independently of the gc-sections setting. Yet it doesn't. Any object file is put into the binary, whether referenced or not. So there are no empty segments to be discarded by -gc-sections. I'm not sure what empty segments you're talking about. segments - = sections. I think I got the 'empty' by browsing the ld option description. Or i dedutcted it from your expression of discarded unused content. Are you _sure_ you passed the -gc-sections flag to the linker? no (see below) First, both -ffunction-sections and -gc-sections flags are commented out in your makefile. I tried with and without. The version I posted was the last test (without both). Second, it's '--gc-sections' not '-gc-sections' I tried both :) Third, if you uncomment them and add the second hyphen, you're still not passing --gc-sections flag to the linker, you're passing it to the compiler (which should have resulted in a error message). If you want to pass the --gc-sections flag to the linker via the gcc command line, you need to use either -W,--gc-sections or -Xlinker --gc-sections That's the point. (or nearly, according to the GC manual, it is -Wl,x (which works) I read the ld documentation and missted the fact that the compiler gets the options first, even if added to LDFLAGS. Nevertheless, I don't understand why foo() is added to the binary by the linker default, while it is not referenced and in its own object file. With the use of -Wl, I come to this conclusion: 1) without --gc-sections, the linker keeps ALL code passed to it in an object file, no matter whether anything in an object file is referenced or nothing at all. 2) with use of --gc-sections, the linker will ignore any object files content, if nothing in this object file is referenced from outside 3) using -ffunction-sections AND --gc-sections, the compiler will put any function in its own .text.* (sub)section and the linker will discard any of them which is not referenced, even if in the same object file as other, referenced code. Since 1) is the default, binary files may be unnecessary large by default. Thanks for your clarifications. It makes life a bit easier for me (I can skip some #ifdefs now in the modules), now that I know (I think) how it really works. JMGross
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
On 2010-06-22, JMGross msp...@grossibaer.de wrote: If I understood the linker scripts correctly, the linker will put all .text and .text.* compiler segments into the linker text segment. After the unreferenced .text.* sections are discarded, the remaining ones will all be placed into the .text section in the output file. As I undestood you, the linker should do this for any (complete) object file anyway, independently of the gc-sections setting. The discarding of unreferences sections is enabled by the --gc-sections linker option. Yet it doesn't. Any object file is put into the binary, whether referenced or not. Unless you specify the --gc-sections option linker option. So there are no empty segments to be discarded by -gc-sections. I'm not sure what empty segments you're talking about. segments - = sections. I think I got the 'empty' by browsing the ld option description. Or i dedutcted it from your expression of discarded unused content. unused != empty Are you _sure_ you passed the -gc-sections flag to the linker? no (see below) First, both -ffunction-sections and -gc-sections flags are commented out in your makefile. I tried with and without. The version I posted was the last test (without both). Second, it's '--gc-sections' not '-gc-sections' I tried both :) And both would have produced an error/warning using your posted makefile, which should have prompted you to try figure out what you were doing wrong rather than claiming the feature didn't work: $ make msp430-gcc -g -ffunction-sections --gc-sections -Wa,-ahl=main.lst -O2 -Wall -Werror -mmcu=msp430x149 -Wa,-ahld=main.lst -o main.elf main.c cc1: unrecognized option -fgc-sections' make: *** [main.elf] Error 1 $ make msp430-gcc -g -ffunction-sections -gc-sections -Wa,-ahl=main.lst -O2 -Wall -Werror -mmcu=msp430x149 -Wa,-ahld=main.lst -o main.elf main.c cc1: warning: c-sections': unknown or unsupported -g option msp430-objcopy -O srec main.elf main.hex Third, if you uncomment them and add the second hyphen, you're still not passing --gc-sections flag to the linker, you're passing it to the compiler (which should have resulted in a error message). If you want to pass the --gc-sections flag to the linker via the gcc command line, you need to use either -W,--gc-sections or -Xlinker --gc-sections That's the point. (or nearly, according to the GC manual, it is -Wl,x (which works) Right. Sorry about the typo. I read the ld documentation and missted the fact that the compiler gets the options first, even if added to LDFLAGS. The ld documentation has no way of knowing what program you're passing LDFLAGS to in your Makefile. Nevertheless, I don't understand why foo() is added to the binary by the linker default, while it is not referenced and in its own object file. Because you didn't pass the --gc-sections flag to the linker to tell it to discard unreferenced sections. With the use of -Wl, I come to this conclusion: 1) without --gc-sections, the linker keeps ALL code passed to it in an object file, no matter whether anything in an object file is referenced or nothing at all. Yes. Thats why I said you have to use both the -ffunction-sections and --gc-sections options. 2) with use of --gc-sections, the linker will ignore any object files content, if nothing in this object file is referenced from outside Yes. 3) using -ffunction-sections AND --gc-sections, the compiler will put any function in its own .text.* (sub)section and the linker will discard any of them which is not referenced, even if in the same object file as other, referenced code. Yes. Since 1) is the default, binary files may be unnecessary large by default. Yes. Thanks for your clarifications. It makes life a bit easier for me (I can skip some #ifdefs now in the modules), now that I know (I think) how it really works. -- Grant Edwards grant.b.edwardsYow! I don't understand at the HUMOUR of the THREE gmail.comSTOOGES!!
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
Von: Grant Edwards Gesendet am: 18 Jun 2010 19:09:51 On 2010-06-18, JMGross msp...@grossibaer.de wrote: I dug out some older project files and if I understand their old makefile correctly, all object files were put into a library (.a) and then this was fed into the linker. So maybe this was the reason for the missing code if the project object files inside the library weren't in the right order. That will indeed cause problems. For pretty much all of the linkers I've used, libraries were only processed once at the point in the file list where they were encountered. If an object file later in the list needs something from a library that has already been processed, that symbol will go unresolved. Any project (does not matter which). Compiled with -ffunction-sections and linked with -gc-sections. Now add a dummy function void foo(void){}; After compilation, the function foo is in a segment called .text.foo. So -ffunction-sections work. After linking, the function is in the linked binary. Binaries are identical, no matter whether -gc-sections was used or not. As I've said, doing that works fine for me. By post an example I meant provide source files and a makefile the exhibit the problem so that we can try to fix it. Unfortunately., my boss really dislikes me posting our project code into the world. I didn't set up a separate project for checking. I just took a randomly chosen existing project, added the function foo() to one of the object files and it always appeared in the binary. No matter whether I used the switches or not. Only difference weas that with -ffunction-sections it appeared in a seaction .text.foo rather than .text in the object file assembly listing. Then I put it ito a separate object file, added it to the project and again it was included into the binary. Onother example. Once again any project. One object file was added to the project, containing the above function. Again the binaries are identical, no matter whether -gc-sections was used or not. foo() was always part of the binary. Is it possible that if not ld itself then the linker scripts have been altered in a way that breaks -gc-sections? That's possible. If you can post an example that fails for you and works for us, then we can start trying to track down the source of the problem. If I understood the linker scripts correctly, the linker will put all .text and .text.* compiler segments into the linker text segment. So there are no empty segments to be discarded by -gc-sections. (well, empty segments won't add to the binary anyway, as they are empty. So the GCC description of this flag is a bit misleading) The question is why the linker keeps the .text.* parts even if they are never referenced. But I'm not linker script expert at all. I was able to add some more linker segments to provide a base for my fixed bootloader. Then again, I noticed that my code placed there, while never referenced, made it into the binary. (I removed all KEEP statements to be sure) I'd really like to put this kind of options (including optimization settings) into the appropriate source file only (by a pragma) instead of having them active for the whole project (unless one wants to make rather complex makefiles) yes, that would be nice, but it would be very difficult due to some fundamental architecture decisions that were made in both gcc and binutils a long time ago. Not really. OK, then submit a patch. I didn't mean that it would be easy NOW and even less fo ME, who might have the imagination but definitely not the time nor the clearance form my boss to read into the compiler code and apply any fixes. Abd when I leave office, I try to forget all about MSP and ATMega and all this. Based on what I've seen from my work on gcc and binutils, it looked pretty difficult to me. Perhaps my understanding of gcc/binutils internals isn't as good as yours. I wouldn't say this. But I often discovered that knowing too much won't let you see the forest because of the trees. When workign on a problem, I never tke the same path as the one before me because if I so, I'll most certainly end up in the same dead end as he did. Every problem is a brain-maze from your current position to the intended goal. If you follow the thoughts of others, you'll never be first with the solution. Either you'll fail like them or they will find the solution before you and you can give up immediately. Entering the contest later only makes sense if you go a different way. Hmmm, backwards compatibility considerations are only neccessary if something may have unexpected side-effects to the unaware. The main side-effect is the way sections are named. It's possible there are side-effects to the way code is optimized, but I've never seen that. Hmm, since both, naming of the sections and optimization are made by the compiler anyway (and not by the user, at least for 99% of all users), there are no possible side-effects (other
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
On 2010-06-21, JMGross msp...@grossibaer.de wrote: Unfortunately., my boss really dislikes me posting our project code into the world. Yes, bosses can be funny that way. I didn't set up a separate project for checking. I just took a randomly chosen existing project, added the function foo() to one of the object files and it always appeared in the binary. No matter whether I used the switches or not. Only difference weas that with -ffunction-sections it appeared in a seaction .text.foo rather than .text in the object file assembly listing. Then I put it ito a separate object file, added it to the project and again it was included into the binary. Onother example. Once again any project. One object file was added to the project, containing the above function. Again the binaries are identical, no matter whether -gc-sections was used or not. foo() was always part of the binary. Is it possible that if not ld itself then the linker scripts have been altered in a way that breaks -gc-sections? That's possible. If you can post an example that fails for you and works for us, then we can start trying to track down the source of the problem. If I understood the linker scripts correctly, the linker will put all .text and .text.* compiler segments into the linker text segment. After the unreferenced .text.* sections are discarded, the remaining ones will all be placed into the .text section in the output file. So there are no empty segments to be discarded by -gc-sections. I'm not sure what empty segments you're talking about. (well, empty segments won't add to the binary anyway, as they are empty. So the GCC description of this flag is a bit misleading) The question is why the linker keeps the .text.* parts even if they are never referenced. Are you _sure_ you passed the -gc-sections flag to the linker? Linktest.c: int main(void){ }//main() dummy.c: void foo(void){ } makefile: #put the name of the project here NAME = Linktest #put your C sourcefiles here SRC = $(NAME).c dummy.c #put additional assembler source file here ASRC = #additional includes to compile INC = #define include path for common code files INCSRC = ../EPOS_COMMON_3 #put the name of the target mcu here MCU = msp430x5438 #compiler flags CPFLAGS = -std=gnu99 -g -Os -Wall -Wcast-align -Wcast-qual -Wimplicit -Wnested-externs -Winline \ -Wpointer-arith -Wredundant-decls -Wreturn-type -Wshadow -Wstrict-prototypes -Wswitch -Wunused -Wundef \ -Wunreachable-code #linker flags LDFLAGS = #-- # MSPGCC standard Makefile part 3 # - ## BLOCK 1) define some variables based on the MSP base path in $(MSP) ### CC = @c:/Programme/msp430/mspgcc_0812/bin/msp430-gcc AS = @c:/Programme/msp430/mspgcc_0812/bin/msp430-gcc -x assembler-with-cpp AR = @c:/Programme/msp430/mspgcc_0812/bin/msp430-ar RM = @rm -f RN = @mv OUT = coff CP = cp BIN = @c:/Programme/msp430/mspgcc_0812/bin/msp430-objcopy SIZE= @c:/Programme/msp430/mspgcc_0812/bin/msp430-size -t RAMUSAGE = @c:/Programme/msp430/mspgcc_0812/bin/msp430-ram-usage INCDIR = . OBJDIR = obj TRGDIR = lib BINDIR = bin LIBDIR = $(MSP)/msp430/lib SHELL = sh.exe DUMP= @c:/Programme/msp430/mspgcc_0812/bin/msp430-objdump JTAG= @c:/Programme/msp430/mspgcc_0812/bin/msp430-jtag TITXT = @c:/Programme/msp430/mspgcc_0812/bin/ihex2titext ## BLOCK 3) define all project specific object files ## OBJ = $(ASRC:.s=.o) $(SRC:.c=.o) CPFLAGS += -mmcu=$(MCU) # -ffunction-sections ASFLAGS += -mmcu=$(MCU) LDFLAGS += -mmcu=$(MCU) # -gc-sections ## BLOCK 5) compile: instructions to create assembler and/or object files from C source ## %.o: %.c $(CC) -c $(CPFLAGS) -Wa,-ahlms=$(addprefix $(OBJDIR)/,$(notdir $(:.c=.lst))) -I$(INCDIR) -I$(INCSRC) $ -o $(OBJDIR)/$@ $(SIZE) $(OBJDIR)/$@ | grep -e .o %.s : %.c $(CC) -S $(CPFLAGS) -I$(INCDIR) -I$(INCSRC) $ -o $(OBJDIR)/$@ ## BLOCK 6) assemble: instructions to create object file from assembler files ## %.o : %.s $(AS) -c $(ASFLAGS) -I$(INCDIR) $ -o $(OBJDIR)/$@ ## BLOCK 7) arch: instructions to create library output file from object files ## $(NAME).elf : $(OBJ) $(CC) $(LDFLAGS) $(addprefix $(OBJDIR)/,$(OBJ)) -o $(TRGDIR)/$(NAME).elf $(NAME).hex : $(NAME).elf $(BIN) -O
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
On 2010-06-21, Grant Edwards grant.b.edwa...@gmail.com wrote: Thank you for posting a real example. Now we can figure out what's going on. First, both -ffunction-sections and -gc-sections flags are commented out in your makefile. Second, it's '--gc-sections' not '-gc-sections' Oops. That one's my fault. I just noticed that I've been typing it incorrectly with a single preceding hyphen during this discussion. Third, if you uncomment them and add the second hyphen, you're still not passing --gc-sections flag to the linker, you're passing it to the compiler (which should have resulted in a error message). If you want to pass the --gc-sections flag to the linker via the gcc command line, you need to use either -W,--gc-sections or -Xlinker --gc-sections -- Grant Edwards grant.b.edwardsYow! Xerox your lunch at and file it under sex gmail.comoffenders!
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
On 2010-06-15, Grant Edwards grant.b.edwa...@gmail.com wrote: On 2010-06-15, JMGross msp...@grossibaer.de wrote: The suggested compiler/linker flags, however, let the compiler treat each function as a separate compilation unit, starting at its own 0-offset address. [...] Also, it keeps the compiler for doing optimizations like common subexpression elimination or using the most efficient way to call functions or access variables, as they are all referenced as externals. I'd also be interested in seeing examples of that. I've only got one MSP430 project laying around at the moment, and it's pretty small: only about 1KB of code. Compiling with -O2 generates the exact same code with -ffunction-sections as it does without. If somebody does come across a situation where -ffunction-sections causes worse (or just different) code to be generated, it would be nice if you could let the list know. Even if there isn't anything we can do to improve the code generation, it will at least allow other mspgcc users to make an intelligent tradeoff decision. -- Grant Edwards grant.b.edwardsYow! ONE LIFE TO LIVE for at ALL MY CHILDREN in ANOTHER gmail.comWORLD all THE DAYS OF OUR LIVES.
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
- Ursprüngliche Nachricht - Von: Grant Edwards Gesendet am: 17 Jun 2010 21:01:31 On 2010-06-17, JMGross msp...@grossibaer.de wrote: [I don't suppose you could wrap lines in your posts?] I'll try. :) Normally, the receivers mail program should do if necessary. (You don't use plain old unix mail, don't you?) Personally, I don't like the way I get answers wrapped back. It reminds me of a poem ratehr than a conversation. It interrupts the flow of reading and leaves lots of unused empty white space on the right side of the screen while it keeps me scrolling. Not with the gc-sections feature. But I'm pretty sure it happened with object files and not just libraries. (And I'm sure that no libraries were linked before the object files, but maybe dependent libraries in the wrong order) I've never heard of that issue occuring with object files, and based on my understanding of how the linker works, I don't see how it could happen. None of my current MSP or ATMega projects actually uses any library except for the stdlib. No own or foreing ones. And never did. Since I remember having this kind of problems somewhere in the past, it thought it must have been with the object files. I dug out some older project files and if I understand their old makefile correctly, all object files were put into a library (.a) and then this was fed into the linker. So maybe this was the reason for the missing code if the project object files inside the library weren't in the right order. If you do come across a case of -ffunction-sections and -gc-sections not working, please post it. It should work, and I know for a fact that it used to. Following example: Any project (does not matter which). Compiled with -ffunction-sections and linked with -gc-sections. Now add a dummy function void foo(void){}; After compilation, the function foo is in a segment called .text.foo. So -ffunction-sections work. After linking, the function is in the linked binary. Binaries are identical, no matter whether -gc-sections was used or not. Onother example. Once again any project. One object file was added to the project, containing the above function. Again the binaries are identical, no matter whether -gc-sections was used or not. foo() was always part of the binary. Is it possible that if not ld itself then the linker scripts have been altered in a way that breaks -gc-sections? You said that compile may not do any optimization that crosses the boundary between functions. Now you're saying it's only certain _types_ of cross-function optimization that can't be done. That may be true, though I can't think of any. If an optimization crosses the boundary of a section, it makes the use of separate sections useless, as both are always needed. Only that they could be split into two different target (flash) segments, if the optimization allows them moving that far apart. If foo() is kept and bar() is not, what about the shared code? The compiler could put the shared code in a third section and call it from both foo() and bar(). Of course that's a possible workaround. I'd really like to put this kind of options (including optimization settings) into the appropriate source file only (by a pragma) instead of having them active for the whole project (unless one wants to make rather complex makefiles) yes, that would be nice, but it would be very difficult due to some fundamental architecture decisions that were made in both gcc and binutils a long time ago. Not really. Even to have the pragma happening at the start of a compilation unit (where it shouldn't make any difference whether the compiler is started with a commandline option or whether it is the first thing it sees) would be a big step ahead. Else I'd vote for a pre-precompiler which takes the source, scans it or pragmas and then adds/adjusts the compiler options according to the pragmas found. Just an idea because I had a case where optimization was breaking the code and I had to compile this without optimization. And I had to write an unnecessary complex addition to the default makefile so the rest of the project would compile optimized. The worst part of it was that this makefile anomaly MUST be added to every project using this code. If you forgot it, the code was crashing. With the option inside the code, things would be much easier, even if not working selectively on parts of the compilation unit. Old Borland C++ 3.1 allowed optimizations different for every function and sometimes it was really needed. It's a shame that they didn't find a way to do it for GCC too. The last fix to gcc for -ffunction-sections -fdata-sections support went in at the end of May 2008, so I would expect the 12/2008 build of gcc to work. I'm not sure what ld 060404 means. ld should have version number like 2.19.3. What I can say is that it worked for me the last time I tried it, and others have reported it working more recently. D:\msp430-ld -v GNU ld
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
On 2010-06-18, JMGross msp...@grossibaer.de wrote: I dug out some older project files and if I understand their old makefile correctly, all object files were put into a library (.a) and then this was fed into the linker. So maybe this was the reason for the missing code if the project object files inside the library weren't in the right order. That will indeed cause problems. For pretty much all of the linkers I've used, libraries were only processed once at the point in the file list where they were encountered. If an object file later in the list needs something from a library that has already been processed, that symbol will go unresolved. If you do come across a case of -ffunction-sections and -gc-sections not working, please post it. It should work, and I know for a fact that it used to. Following example: Any project (does not matter which). Compiled with -ffunction-sections and linked with -gc-sections. Now add a dummy function void foo(void){}; After compilation, the function foo is in a segment called .text.foo. So -ffunction-sections work. After linking, the function is in the linked binary. Binaries are identical, no matter whether -gc-sections was used or not. As I've said, doing that works fine for me. By post an example I meant provide source files and a makefile the exhibit the problem so that we can try to fix it. Onother example. Once again any project. One object file was added to the project, containing the above function. Again the binaries are identical, no matter whether -gc-sections was used or not. foo() was always part of the binary. Is it possible that if not ld itself then the linker scripts have been altered in a way that breaks -gc-sections? That's possible. If you can post an example that fails for you and works for us, then we can start trying to track down the source of the problem. I'd really like to put this kind of options (including optimization settings) into the appropriate source file only (by a pragma) instead of having them active for the whole project (unless one wants to make rather complex makefiles) yes, that would be nice, but it would be very difficult due to some fundamental architecture decisions that were made in both gcc and binutils a long time ago. Not really. OK, then submit a patch. Based on what I've seen from my work on gcc and binutils, it looked pretty difficult to me. Perhaps my understanding of gcc/binutils internals isn't as good as yours. The last fix to gcc for -ffunction-sections -fdata-sections support went in at the end of May 2008, so I would expect the 12/2008 build of gcc to work. I'm not sure what ld 060404 means. ld should have version number like 2.19.3. What I can say is that it worked for me the last time I tried it, and others have reported it working more recently. D:\msp430-ld -v GNU ld version 060404 20060404 D:\ Hmmm, now that you ask, I checked the file date and it was May 2006. Looks like I called the wrong one. :( The ld version that's called by msp430-gcc is GNU ld (GNU binutils) 2.18 (I checked the makefile output) I think that should be recent enough. Yes, if the linker supports changing address modes, then it does move the following code. Then it needs to also adjust all symbolic mode accesses, even local ones which are not subject to relocation. Quite some work. And requires a lot special knowledge about the target system structure. Yes it does. That's why it's supported on a per-target basis and not all targets have had support for that sort of thing added. If the linker goes through the object file, analyzes every instruction (if it is an instruction)... well, why do we have an assembler stage? :) Various reasons -- not the least among them is history: when you first write a compiler, there is often an existing assembler and linker that you can use. Well, I'm better safe than sorry and I guess someone else did too. Why else is this whole -ffunction-sections thing an option and disabled by default? Because it's a somewhat new feature and it's not the way people are used to having things work. When a new feature gets added, it's usually disabled by default in order to preserve as much backwards-compatibilty as possible. Hmmm, backwards compatibility considerations are only neccessary if something may have unexpected side-effects to the unaware. The main side-effect is the way sections are named. It's possible there are side-effects to the way code is optimized, but I've never seen that. -- Grant Edwards grant.b.edwardsYow! What's the MATTER at Sid? ... Is your BEVERAGE gmail.comunsatisfactory?
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
- Ursprüngliche Nachricht - Von: Grant Edwards An: mspgcc-users@lists.sourceforge.net Gesendet am: 16 Jun 2010 21:43:44 On 2010-06-16, JMGross msp...@grossibaer.de wrote: I had this happen long time ago when I included the different object files or libraries in the wrong order with GCC under linux. After reordering them so that their contend had already been referenced, all was well. I think I had similar problems (immediately solved) with mspgcc. Those problems were with the --gc-sections feature? It sounds to me like you were linking libraries before you linked the object files that referenced the routines in the library. That's a different, unrelated issue. Not with the gc-sections feature. But I'm pretty sure it happened with object files and not just libraries. (And I'm sure that no libraries were linked before the object files, but maybe dependent libraries in the wrong order) But it is possible that the setup made a library first from part of the object files and then linked it. As I said, it happened long ago. I inherited these projects from my predecessor in the job. I then reorganized the code base (and the makefiles) and never got into this kind of problems again. I even cannot tell anymore whether it was a gcc or an mspgcc project where this happened or both. If these compiler flags allow treating different functions in the same files to be kept or discarded depending of whether they are used, it's obvious that they need to be be considered unused when they haven't been referenced yet. The garbage collection algorithm used by the linker shouldn't depend what order you link the object files. If you've got examples where it seems to matter, please post it because that's a bug and needs to be fixed. I'm sorry, but everything that could be used to check or even reproduce this behaviour has been relocated to the null device long ago. Unless the linker has been greatly improved since then, the problem should be there. Maybe I'm wrong. You seem to be assuming a single-pass linker. It works in two passes. First it reads all of the object files. Then it starts at all of the nodes (symbols) marked as keep and traverses the reference graph marking all reachable nodes. When it's done traversing the graph, it discards any nodes that haven't been reached from the initial set of keep nodes. When I read last time about the inner workings of the linking process, things were different, But of course there have been many improvements in the past years and I didn't really care anyway. And with todays surplus of memory and CPU power, it makes no difference keeping everything first and sorting out things later. About the reduced effectiveness of the optimization, this one is obvious. If the linker is allowed to include or discard parts of a compilation unit depending of their usage, the compiler may not do any optimization that crosses the boundary between functions. I'm afraid that's not at all obvious to me. Example: A C file contains two functions: foo() and bar(). foo() is called by various external functions. bar() is called only by foo(). The compiler can inline bar() without causing any problems. Sure, but the optimization process sometimes generates code where foo() and bar() share common code after optimization. If foo() is kept and bar() is not, what about the shared code? After (re-)reading the explanation of -ffunction-sections, it looks like every function is placed in its own section, so the optimizer should not optimize across functions anyway, generating less-efficient code since it isn't known at compile-time whether the shared code will be still available after linking. I'm sure I've seen this kind of optimizations not too long ago. But don't aske me for an example. Of cource the outcome won't be less efficient than having both functions in separate compilation units. I'd really like to put this kind of options (including optimization settings) into the appropriate source file only (by a pragma) instead of having them active for the whole project (unless one wants to make rather complex makefiles) Anyway, I just tried to use the -ffunction-sections and -gc-sections flags and while the compiler now places the functions in separate sections like .text.foo, the linker does not remove them from the build at all. And I'm certain that the two functions in question are not referenced ever as I just added them to the code. Also, I added some sections/moved the vector table and the code/data in these sections is never referenced anywhere, yet they are still in the binary. (and I do not explicitely keep them in the linker script). I wonder what's (not) going on. It's ld 060404, part of the mspgcc build from 12/2008. Even more, I think the linker will keep everything I feed it as source file, whether anything in an object file is ever used or not. I normally only include those object files which _are_ in use,
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
On 2010-06-17, JMGross msp...@grossibaer.de wrote: [I don't suppose you could wrap lines in your posts?] Not with the gc-sections feature. But I'm pretty sure it happened with object files and not just libraries. (And I'm sure that no libraries were linked before the object files, but maybe dependent libraries in the wrong order) I've never heard of that issue occuring with object files, and based on my understanding of how the linker works, I don't see how it could happen. But it is possible that the setup made a library first from part of the object files and then linked it. It will definitely happen with library files. When the linker encounters a library file, it will only pull in from the library the objects required to resolve any as-yet unresolved symbols. If these compiler flags allow treating different functions in the same files to be kept or discarded depending of whether they are used, it's obvious that they need to be be considered unused when they haven't been referenced yet. The garbage collection algorithm used by the linker shouldn't depend what order you link the object files. If you've got examples where it seems to matter, please post it because that's a bug and needs to be fixed. I'm sorry, but everything that could be used to check or even reproduce this behaviour has been relocated to the null device long ago. If you do come across a case of -ffunction-sections and -gc-sections not working, please post it. It should work, and I know for a fact that it used to. Unless the linker has been greatly improved since then, the problem should be there. Maybe I'm wrong. You seem to be assuming a single-pass linker. It works in two passes. First it reads all of the object files. Then it starts at all of the nodes (symbols) marked as keep and traverses the reference graph marking all reachable nodes. When it's done traversing the graph, it discards any nodes that haven't been reached from the initial set of keep nodes. When I read last time about the inner workings of the linking process, things were different, But of course there have been many improvements in the past years and I didn't really care anyway. And with todays surplus of memory and CPU power, it makes no difference keeping everything first and sorting out things later. About the reduced effectiveness of the optimization, this one is obvious. If the linker is allowed to include or discard parts of a compilation unit depending of their usage, the compiler may not do any optimization that crosses the boundary between functions. I'm afraid that's not at all obvious to me. Example: A C file contains two functions: foo() and bar(). foo() is called by various external functions. bar() is called only by foo(). The compiler can inline bar() without causing any problems. Sure, but the optimization process sometimes generates code where foo() and bar() share common code after optimization. You said that compile may not do any optimization that crosses the boundary between functions. Now you're saying it's only certain _types_ of cross-function optimization that can't be done. That may be true, though I can't think of any. If foo() is kept and bar() is not, what about the shared code? The compiler could put the shared code in a third section and call it from both foo() and bar(). After (re-)reading the explanation of -ffunction-sections, it looks like every function is placed in its own section, so the optimizer should not optimize across functions anyway, generating less-efficient code since it isn't known at compile-time whether the shared code will be still available after linking. The compiler could take measures to make sure that the shared code is avaialable whether either foo() or bar() is called. But this is all rather academic without looking at real code that is somehow adversely affected by the --functions-section option. I'm sure I've seen this kind of optimizations not too long ago. But don't ask me for an example. OK, but there's not much we can do to address worries for which you don't have any real examples. Of cource the outcome won't be less efficient than having both functions in separate compilation units. I'd really like to put this kind of options (including optimization settings) into the appropriate source file only (by a pragma) instead of having them active for the whole project (unless one wants to make rather complex makefiles) yes, that would be nice, but it would be very difficult due to some fundamental architecture decisions that were made in both gcc and binutils a long time ago. Anyway, I just tried to use the -ffunction-sections and -gc-sections flags and while the compiler now places the functions in separate sections like .text.foo, the linker does not remove them from the build at all. Then somebody has done something to break the linker. I used to rely on those features, and I know that they worked -- when I
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
On Thu, Jun 17, 2010 at 3:01 PM, Grant Edwards grant.b.edwa...@gmail.com wrote: On 2010-06-17, JMGross msp...@grossibaer.de wrote: interesting. Still two wasted bytes (I don't think the linker will move the following code and adjust any other jumps if necessary), Yes, if the linker supports changing address modes, then it does move the following code. FWIW, this is a well-known and tricky problem, because you can get circular dependencies: short addressing at location A can only reach site B if site B also uses short addressing, and vice versa. There's a standard algorithm that deals with, for quite some time---I remember first reading about it in the 80s.
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
On 2010-06-17, Przemek Klosowski przemek.klosow...@gmail.com wrote: On Thu, Jun 17, 2010 at 3:01 PM, Grant Edwards grant.b.edwa...@gmail.com wrote: On 2010-06-17, JMGross msp...@grossibaer.de wrote: interesting. Still two wasted bytes (I don't think the linker will move the following code and adjust any other jumps if necessary), Yes, if the linker supports changing address modes, then it does move the following code. FWIW, this is a well-known and tricky problem, because you can get circular dependencies: short addressing at location A can only reach site B if site B also uses short addressing, and vice versa. There's a standard algorithm that deals with, for quite some time---I remember first reading about it in the 80s. Yep, IIRC, it's an example of a large class of non-linear problems that includes modelling of physical systems where changes in the state of a node/cell affects the states of other nodes/cells. You try to find the the best overall approximation to a solution using an iterative approach that makes multiple passes through the data until no more improvements can be made. That sort of an agorithm is called a relaxation algorithm. If I'm remembering things correctly from many years ago, one main groups of problems in that class is calculating the final state of an irregular physical structure when the applied stresses are changed. The structure will relax into a new equilibrium state that minimizes overall strain. Or stress. Or something like that. But don't quote me, I'm an EE. Or maybe I'm incorrectly mixing together unrelated things simply because they all use the world relaxation or relax. -- Grant Edwards grant.b.edwardsYow! I was born in a at Hostess Cupcake factory gmail.combefore the sexual revolution!
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
I had this happen long time ago when I included the different object files or libraries in the wrong order with GCC under linux. After reordering them so that their contend had already been referenced, all was well. I think I had similar problems (immediately solved) with mspgcc. If these compiler flags allow treating different functions in the same files to be kept or discarded depending of whether they are used, it's obvious that they need to be be considered unused when they haven't been referenced yet. (It would be pretty useless to have such a feature if it could be inhibited by circular references of dead code.) Unless the linker has been greatly improved since then, the problem should be there. Maybe I'm wrong. About the reduced effectiveness of the optimization, this one is obvious. If the linker is allowed to include or discard parts of a compilation unit depending of their usage, the compiler may not do any optimization that crosses the boundary between functions. Else either common code may disappear when not linked or a reference is generated that will keep the normally unused other function from being excluded from the build. Or the common part is referenced by both with a branch (instead of a relative jump), making the code less efficient. Also, some addressing modes cannot be used under such a setup. Optimizations INSIDE a function are not touched, of course. Only those across functions (e.g. identical exit code). The common subexpression elimination was a bad example. (I was a bit in haste when I wrote this, it was at the end of my office hours) JMGross - Ursprüngliche Nachricht - Von: Grant Edwards An: mspgcc-users@lists.sourceforge.net Gesendet am: 15 Jun 2010 20:26:25 Betreff: Re: [Mspgcc-users] Unused functions occupying unnecessary memory On 2010-06-15, JMGross msp...@grossibaer.de wrote: The suggested compiler/linker flags, however, let the compiler treat each function as a separate compilation unit, starting at its own 0-offset address. This means teh compiler will not resolve any local references and let it all to the linker. Since all references are passed to the linker, the linker can link or discard every of these sections depending on the open references. What's references from a different module is kept, what's not referenced will be discarded. But it may happen that parts are discarded bwcause not yet referenced by any of the already loaded modules, bu twill be later and then the reference cannot be resolved as the target had been discarded already. If that happens, it's a bug. Can you post an example of that so it can be fixed? Also, it keeps the compiler for doing optimizations like common subexpression elimination or using the most efficient way to call functions or access variables, as they are all referenced as externals. I'd also be interested in seeing examples of that.
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
On 2010-06-16, JMGross msp...@grossibaer.de wrote: I had this happen long time ago when I included the different object files or libraries in the wrong order with GCC under linux. After reordering them so that their contend had already been referenced, all was well. I think I had similar problems (immediately solved) with mspgcc. Those problems were with the --gc-sections feature? It sounds to me like you were linking libraries before you linked the object files that referenced the routines in the library. That's a different, unrelated issue. If these compiler flags allow treating different functions in the same files to be kept or discarded depending of whether they are used, it's obvious that they need to be be considered unused when they haven't been referenced yet. The garbage collection algorithm used by the linker shouldn't depend what order you link the object files. If you've got examples where it seems to matter, please post it because that's a bug and needs to be fixed. (It would be pretty useless to have such a feature if it could be inhibited by circular references of dead code.) True, but that doesn't mean that the object files have to be a partially ordered set. Nodes are not discarded based on a reference-count -- they're discarded based on a reachability. Unless the linker has been greatly improved since then, the problem should be there. Maybe I'm wrong. You seem to be assuming a single-pass linker. It works in two passes. First it reads all of the object files. Then it starts at all of the nodes (symbols) marked as keep and traverses the reference graph marking all reachable nodes. When it's done traversing the graph, it discards any nodes that haven't been reached from the initial set of keep nodes. Are you sure you're not thinking about the requirement that libraries be paritially ordered with respect to referencing objects? About the reduced effectiveness of the optimization, this one is obvious. If the linker is allowed to include or discard parts of a compilation unit depending of their usage, the compiler may not do any optimization that crosses the boundary between functions. I'm afraid that's not at all obvious to me. Example: A C file contains two functions: foo() and bar(). foo() is called by various external functions. bar() is called only by foo(). The compiler can inline bar() without causing any problems. Else either common code may disappear when not linked or a reference is generated that will keep the normally unused other function from being excluded from the build. Sorry, you've lost me. I'm not saying it doesn't happen, but I can't visualize it. Do you have an example? Or the common part is referenced by both with a branch (instead of a relative jump), making the code less efficient. IIRC, the linker will convert long branches into short/relative jumps at link time. At least it does that for all the other targets I use... Also, some addressing modes cannot be used under such a setup. I don't understand why. Can you provide an actual example? Optimizations INSIDE a function are not touched, of course. Only those across functions (e.g. identical exit code). The common subexpression elimination was a bad example. (I was a bit in haste when I wrote this, it was at the end of my office hours) Some things like optmizing addressing modes for far/short destinations have to be done at link time instead of compile time, but I don't see how that hurts anything. -- Grant Edwards grant.b.edwardsYow! This ASEXUAL PIG at really BOILS my BLOOD gmail.com... He's so ... so ... URGENT!!
[Mspgcc-users] Unused functions occupying unnecessary memory
Hi all: I have been noticing that a function that is not used by any module in program gets linked anyway, occupying some precious amount of memory. Suppose that you were sharing a common module but you only needed some functions of it. Is there a way to avoid linking all the unused functions? I am also posting the output of msp430-objdump with an example of the situation: tst_unreachable_code.elf: file format elf32-msp430 Disassembly of section .text: 3100 __init_stack: 3100: 31 40 00 31 mov #12544, r1 ;#0x3100 3104 __low_level_init: 3104: b2 40 80 5a mov #23168, 0x0120 ;#0x5a80 3108: 20 01 310a __do_clear_bss: 310a: 3f 40 00 00 mov #0, r15 ;#0x 310e: 0f 93 cmp #0, r15 ;r3 As==00 3110: 04 24 jz $+10;abs 0x311a 3112: 1f 83 dec r15 ; 3114: cf 43 00 11 mov.b #0, 4352(r15);r3 As==00 3118: fc 23 jnz $-6 ;abs 0x3112 311a __do_copy_data: 311a: 3f 40 00 00 mov #0, r15 ;#0x 311e: 0f 93 cmp #0, r15 ;r3 As==00 3120: 05 24 jz $+12;abs 0x312c 3122: 2f 83 decdr15 ; 3124: 9f 4f 4c 31 mov 12620(r15),4352(r15); 3128: 00 11 312a: fb 23 jnz $-8 ;abs 0x3122 312c __jump_to_main: 312c: 30 40 3a 31 br #0x313a ; 3130 __ctors_end: 3130: 80 00 .word 0x0080; 3132: 4a 31 jn $+662 ;abs 0x33c8 #include io.h 3134 foo: void foo(void) { /* A function not used by anybody in program but, * however, is linked anyway, wasting ROM space. */ P1OUT ^= 0x02; /* Toggle P1.1 */ 3134: e2 e3 21 00 xor.b #2, 0x0021 ;r3 As==10 } 3138: 30 41 ret 313a main: int main (void) { 313a: 31 40 00 31 mov #12544, r1 ;#0x3100 WDTCTL=WDTPW+WDTHOLD; /* Stop watchdog */ 313e: b2 40 80 5a mov #23168, 0x0120 ;#0x5a80 3142: 20 01 while(1) { P1OUT ^= 0x01; /* Toggle P1.0 */ 3144: d2 e3 21 00 xor.b #1, 0x0021 ;r3 As==01 3148: fd 3f jmp $-4 ;abs 0x3144 314a _unexpected_: } }// end main 314a: 00 13 reti Disassembly of section .vectors: ffc0 InterruptVectors: ffc0: 30 31 jn $+610 ;abs 0x222 ffc2: 30 31 jn $+610 ;abs 0x224 ffc4: 30 31 jn $+610 ;abs 0x226 ffc6: 30 31 jn $+610 ;abs 0x228 ffc8: 30 31 jn $+610 ;abs 0x22a ffca: 30 31 jn $+610 ;abs 0x22c ffcc: 30 31 jn $+610 ;abs 0x22e ffce: 30 31 jn $+610 ;abs 0x230 ffd0: 30 31 jn $+610 ;abs 0x232 ffd2: 30 31 jn $+610 ;abs 0x234 ffd4: 30 31 jn $+610 ;abs 0x236 ffd6: 30 31 jn $+610 ;abs 0x238 ffd8: 30 31 jn $+610 ;abs 0x23a ffda: 30 31 jn $+610 ;abs 0x23c ffdc: 30 31 jn $+610 ;abs 0x23e ffde: 30 31 jn $+610 ;abs 0x240 ffe0: 30 31 interrupt service routine at 0x3130 ffe2: 30 31 interrupt service routine at 0x3130 ffe4: 30 31 interrupt service routine at 0x3130 ffe6: 30 31 interrupt service routine at 0x3130 ffe8: 30 31 interrupt service routine at 0x3130 ffea: 30 31 interrupt service routine at 0x3130 ffec: 30 31 interrupt service routine at 0x3130 ffee: 30 31 interrupt service routine at 0x3130 fff0: 30 31 interrupt service routine at 0x3130 fff2: 30 31 interrupt service routine at 0x3130 fff4: 30 31 interrupt service routine at 0x3130 fff6: 30 31 interrupt service routine at 0x3130 fff8: 30 31 interrupt service routine at 0x3130 fffa: 30 31 interrupt service routine at 0x3130 fffc: 30 31 interrupt service routine at 0x3130 fffe: 00 31 interrupt service routine at 0x3100 Thank you very much for your attention. Alex
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
That's normal. The linker cannot know whether a function inside a compilation unit is perhaps already directly accessed from inside its compilation unit. So if ANY of teh global symbols of this compilation unit is referenced from another module, it will be linked-in completely. If you want your code to be linked only if required, you need to put any independent code into its own c file. This is the way the stdlib is done. On the other side, the linker will not include any compilation unit that is not referenced at all, even if it has references to others. So if you e.g. create your interrupt vector table as a separate C file, it will not be linked into the final code, as nobody ever references it. If you need it linked, you'll need to take special care of it. Simplest way is to generate a dummy reference to e.g. the reset vector anywhere in your program. JMGross - Ursprüngliche Nachricht - Von: Alex Polbach An: mspgcc-users@lists.sourceforge.net Gesendet am: 15 Jun 2010 11:02:58 Betreff: [Mspgcc-users] Unused functions occupying unnecessary memory Hi all: I have been noticing that a function that is not used by any module in program gets linked anyway, occupying some precious amount of memory. Suppose that you were sharing a common module but you only needed some functions of it. Is there a way to avoid linking all the unused functions? I am also posting the output of msp430-objdump with an example of the situation:
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
On 2010-06-15, Alex Polbach alex.polb...@wimet.es wrote: I have been noticing that a function that is not used by any module in program gets linked anyway, occupying some precious amount of memory. Suppose that you were sharing a common module but you only needed some functions of it. Is there a way to avoid linking all the unused functions? Yes. Add -ffunction-sections to CFLAGS. Then link add --gc-sections to LDFLAGS. If you also want to discard unused variables, add -ffdata-sections to the compiler flags. See the ld and gcc info pages for details. -- Grant Edwards grant.b.edwardsYow! Here I am in 53 at B.C. and all I want is a gmail.comdill pickle!!
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
On 2010-06-15, Grant Edwards grant.b.edwa...@gmail.com wrote: On 2010-06-15, Alex Polbach alex.polb...@wimet.es wrote: I have been noticing that a function that is not used by any module in program gets linked anyway, occupying some precious amount of memory. Suppose that you were sharing a common module but you only needed some functions of it. Is there a way to avoid linking all the unused functions? Yes. Add -ffunction-sections to CFLAGS. Then link add --gc-sections to LDFLAGS. If you also want to discard unused variables, add -ffdata-sections to the compiler flags. See the ld and gcc info pages for details. NB: I haven't tested these options with mspgcc in a long time, but at one point several years ago they worked fine. -- Grant Edwards grant.b.edwardsYow! Excuse me, but didn't at I tell you there's NO HOPE gmail.comfor the survival of OFFSET PRINTING?
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
Thanks a lot for so fast answers!! I have added both flags to CFLAGS and LDFLAGS and they work just fine. Very neat solution. Alex On 2010-06-15, Grant Edwards grant.b.edwa...@gmail.com wrote: On 2010-06-15, Alex Polbach alex.polb...@wimet.es wrote: I have been noticing that a function that is not used by any module in program gets linked anyway, occupying some precious amount of memory. Suppose that you were sharing a common module but you only needed some functions of it. Is there a way to avoid linking all the unused functions? Yes. Add -ffunction-sections to CFLAGS. Then link add --gc-sections to LDFLAGS. If you also want to discard unused variables, add -ffdata-sections to the compiler flags. See the ld and gcc info pages for details. NB: I haven't tested these options with mspgcc in a long time, but at one point several years ago they worked fine. -- Grant Edwards grant.b.edwardsYow! Excuse me, but didn't at I tell you there's NO HOPE gmail.comfor the survival of OFFSET PRINTING?
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
On 2010-06-15, Alex Polbach alex.polb...@wimet.es wrote: Thanks a lot for so fast answers!! I have added both flags to CFLAGS and LDFLAGS and they work just fine. Very neat solution. I'm not sure how much those features get used with mspgcc, but I found them to be invaluable if you want to share code between projects or if you want to be able to do different builds of a project that have different features enabled: when you disable (e.g. with #if/#endif) a function, then all of the code/data that were used only by that function is automatically left out. IIRC it worked even when you disable code with if(0) {}. When I first implemented those features for mspgcc there were obscure cases where a function would get discarded when it shouldn't have been due to omissions in the linker script. AFAIK, that shouldn't be a problem, but it's something to keep it in mind if you get linker errors due to inexplicably missing symbols: the solution is to mark the symbol with the KEEP() command in the linker script. -- Grant Edwards grant.b.edwardsYow! Will it improve my at CASH FLOW? gmail.com
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
If you use #ifdef/#endif, the part in between isn't compiled at all. The preprocessor will not forward the source to the compiler and the compiler never sees it. I use it often to customize parts of a function depending on the used processor and/or architecture. So I can conpile a function for ATMega and several MSPs and depending on the current project, some code is different or left out. Using if(0) (or while(0)), however, generates unreachable code which is eliminated by the comiler optimization run. It is compiled, detected as never executed and discarded. And also not part of the compiled code and therefore never linked. The suggested compiler/linker flags, however, let the compiler treat each function as a separate compilation unit, starting at its own 0-offset address. This means teh compiler will not resolve any local references and let it all to the linker. Since all references are passed to the linker, the linker can link or discard every of these sections depending on the open references. What's references from a different module is kept, what's not referenced will be discarded. But it may happen that parts are discarded bwcause not yet referenced by any of the already loaded modules, bu twill be later and then the reference cannot be resolved as the target had been discarded already. Also, it keeps the compiler for doing optimizations like common subexpression elimination or using the most efficient way to call functions or access variables, as they are all referenced as externals. If you want it or not depends on your project. JMGross. - Ursprüngliche Nachricht - Von: Grant Edwards An: mspgcc-users@lists.sourceforge.net Gesendet am: 15 Jun 2010 17:54:00 Betreff: Re: [Mspgcc-users] Unused functions occupying unnecessary memory On 2010-06-15, Alex Polbach alex.polb...@wimet.es wrote: Thanks a lot for so fast answers!! I have added both flags to CFLAGS and LDFLAGS and they work just fine. Very neat solution. I'm not sure how much those features get used with mspgcc, but I found them to be invaluable if you want to share code between projects or if you want to be able to do different builds of a project that have different features enabled: when you disable (e.g. with #if/#endif) a function, then all of the code/data that were used only by that function is automatically left out. IIRC it worked even when you disable code with if(0) {}. When I first implemented those features for mspgcc there were obscure cases where a function would get discarded when it shouldn't have been due to omissions in the linker script. AFAIK, that shouldn't be a problem, but it's something to keep it in mind if you get linker errors due to inexplicably missing symbols: the solution is to mark the symbol with the KEEP() command in the linker script. -- Grant Edwards grant.b.edwardsYow! Will it improve my at CASH FLOW? gmail.com -- ThinkGeek and WIRED's GeekDad team up for the Ultimate GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the lucky parental unit. See the prize list and enter to win: http://p.sf.net/sfu/thinkgeek-promo ___ Mspgcc-users mailing list Mspgcc-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mspgcc-users
Re: [Mspgcc-users] Unused functions occupying unnecessary memory
On 2010-06-15, JMGross msp...@grossibaer.de wrote: The suggested compiler/linker flags, however, let the compiler treat each function as a separate compilation unit, starting at its own 0-offset address. This means teh compiler will not resolve any local references and let it all to the linker. Since all references are passed to the linker, the linker can link or discard every of these sections depending on the open references. What's references from a different module is kept, what's not referenced will be discarded. But it may happen that parts are discarded bwcause not yet referenced by any of the already loaded modules, bu twill be later and then the reference cannot be resolved as the target had been discarded already. If that happens, it's a bug. Can you post an example of that so it can be fixed? Also, it keeps the compiler for doing optimizations like common subexpression elimination or using the most efficient way to call functions or access variables, as they are all referenced as externals. I'd also be interested in seeing examples of that. -- Grant Edwards grant.b.edwardsYow! I'm a nuclear at submarine under the gmail.compolar ice cap and I need a Kleenex!