Menu

#452 Remove unused functions at link time

open
nobody
None
5
2025-12-19
2015-08-11
No

Removing unused functions at link time is an often-requested feature.
Currently this already works when using libries with one module per independent global symbol. But it seems users also want the optimization to work with more coarse-grained modules.

Philipp

Related

Discussion: Dead code removal in SDCC Z80
Feature Requests: #624
Feature Requests: #950

Discussion

  • alvin

    alvin - 2015-08-16

    This should be made a compile time option as it's quite common to have assembly subroutines interact with C functions and some of the references to C functions may come only from external asm subroutines.

     
  • Wolle K.

    Wolle K. - 2015-09-15

    Why not let assember output a list of global symbols referenced for each global label, so linker can build a tree of symbols in use, discarding the others?

     
    • Philipp Klaus Krause

      Well, the linker basically already can do what is needed. After all it works with library files:
      Currently, the assembler creates one .rel "module" per input file. one can then combine these via ar into libraries.
      The linker then gets some .rel files and some libraries. It includes all .rel files fully, and picks from the libraries only those modules needed to satisfy dependencies.

      So basically, to get the linker to omit unused functions that are not in separate modules in libraries, we'd need to find a way to have multiple modules per .rel file, and make the linker treat .rel files like libraries. Or make sdcc create libraries instead of .rel files (then the question becomes how to invoke the assembler) from c files that we then pass to the linker.

       
      • Philipp Klaus Krause

        sdas (as well as current upstream asxxxx) will still create one module per input file (multiple .module directives in assembler source are ignored by sdas, and give an error with current upstream asxxxx).

        So we could maybe try one of these approaches, or a variant thereof.

        1) Make sdas create one module per .module line, with the output either being a .rel file containing multiple modules or an ar archive containing mutiple modules. Feed this into the linker as a library.

        2) Make SDCC split the assembler output into multiple files, have them assembled separately, then merge them via ar, to pass the resulting library into the linker.

         
        • Janko Stamenović

          The minimum change, from the linker side, is "simply" SDCC creating a rel file per function, and pass the flag "link only if needed" (the same status that the rel files have when in the .lib). Only that flag would have to be added to the linker.
          The non trivial part, from the SDCC perspective, of maintaining the expectations of a "C compilation units" is creating all these additional rel files.
          But that would also necessitate different build organization.
          The more user friendly way (to keep existing make files the same) is surely still one .rel file per C file but which would contain "sub-rel linking units -- maybe 'submodules'? " which could be separately linked on demand.

          Edit: I think both kinds of linkage would have to be preserved and that it should be possible to specify each of them per submodule: these which have to be unconditionally linked in, and these that could be linked only if needed.

           

          Last edit: Janko Stamenović 2024-11-07
          • Janko Stamenović

            The "maximal" change, from the linker side, would probably be if the linker would, independently of SDCC, internally "virtually" split the currently generated .rel files, for example, so that all labels which aren't marked as "need to be linked in unconditionally always" start the chunks which could be linked but are linked only if used from the "always" chunks.
            SDCC would only have to declare which labels have to be unconditionally present, and all other decisions what is left out would be done by the linker.

             
            • Philipp Klaus Krause

              I think we'd still need a way for SDCC to communicate through to the linker what the "modules" (i.e minimal units to be either completely included or excluded) are.

               
              👍
              1
              • Janko Stamenović

                I agree, it's very probable: for example: if the compiler introduces labels which aren't used but the code actually falls through, the result would be wrong if the code starting with such a label would be removed by the linker.

                 
              • Janko Stamenović

                Also: regarding "where a function begins and ends" I see in the output of gcc https://godbolt.org/z/6McEb7Wdq .cfi_startproc and .cfi_endproc which are also needed to construct call frame information (and I can't claim that they introduced it for the same reasons that are interested to us, as the x64 ABI which I'm familiar with expects to have necessary frame information about every function during the code execution, to be able to "unwind" them when the native "exceptions" happen, I'm aware of the necessity there for that).
                I'm mentioning this only because it allows marking the begin and the end of the function without introducing new labels in assembly.

                 
  • Franz

    Franz - 2016-12-22

    I would really appreciate it if this feature would be implemented soon! To be honest I find it really dissappointing that this feature is not already included in SDCC. This should have a much higher priority!

     
    👍
    1
  • Jeff Trull

    Jeff Trull - 2023-01-07

    I find this to be an important feature, myself. While it's true that you can write code from scratch that is organized to get around this limitation, porting existing code (what I'm trying to do today) is a real challenge.

    Can someone point us to the code in aslink that would need to change to implement this feature? A rough idea is fine.

     
    • Benedikt Freisen

      Quite a lot would have to change in aslink, because it is a rather dumb linker and we are also using an ancient fork of it.
      If you just want to make it work and do not care about the exact toolchain, you can technically use the GNU assembler and linker, instead. There is a Z80 fork of these somewhere out there and there was also a fork of SDCC at some point that could output matching syntax. I don't know much about these experiments, though.

       
      • Jeff Trull

        Jeff Trull - 2023-01-08

        Thank you, using a different version sounds appealing. Is there GNU support for mcs51? And where would I find the most modern version of aslink (Google only gives me sdcc hits for it). Thanks!

         
    • Maarten Brock

      Maarten Brock - 2023-01-09

      You can also subdivide your sources into the smallest pieces possible and place the resulting object (.rel) files in a library and let the linker link against the lib. The linker will take the (complete!) object files it needs and leave out the ones it doesn't need at all.

       
      👍
      1
  • Aoineko

    Aoineko - 2023-09-21

    The z80 compiler is designed for machines with very limited resources. All the useless code that ends up in the final program is a big waste of space.
    And the solution, 1 file = 1 function, is not at all applicable to a medium-sized library.
    In my MSX library, I have several hundred functions... having several hundred files to maintain would just be hell.

     
    👍
    1

    Last edit: Aoineko 2023-09-21
  • Ragozini Arturo

    Ragozini Arturo - 2025-12-14

    Any news about this feature?

     
    • Aoineko

      Aoineko - 2025-12-14

      According to a recent news, this feature may be part of the work founded by the NGI0 Commons Fund (thanks to them).

      That said, we don't yet have an estimated delivery date nor details on how this may be implemented.
      We can only hope for the best. :)

       
    • Benedikt Freisen

      Keep an eye on section A2 in [NGI0-Commons-SDCC] and the monthly progress reports at the top of that page.
      There is some progress, but the merging of sdas and upstream asxxxx has to be completed before this kind of functionality can be sensibly added.

       
      👍
      1

      Related

      Wiki: NGI0-Commons-SDCC


Log in to post a comment.

MongoDB Logo MongoDB