#321 Provide option to intiialise globals directly

open
nobody
None
6
2013-08-19
2011-05-09
Brian Ruthven
No

I'm probably a bit out on a limb here, but I'm running the Z80 port targetting an all-RAM config (a bit like CP/M does). The gsinit code hurts me a bit, and steals some valuable space. I realise this is required for a program which will ultimately reside in ROM, but it would be nice in my case (and save me around 300 bytes) if globals could be initialised at declaration time using the relevant .db or equivalent assembler directive.

My current proposed workaround (although I've not tested it thoroughly yet) is to rearrange the linker segments in my custom crt such that I get _CODE followed by _DATA, then _GSINIT section. Thus, once the call to gsinit is completed, that code is not needed again, so this space is reclaimed by main() for use with the dynamic memory allocator (again, my own), by locating the boundary between _DATA and _GSINIT and overwriting _GSINIT as the program runs. It's a bit clumsy, but once I got my head around the linker, seems possible.

An option such as --allocate-globals-directly or equivalent would help avoid this tinkering.

Having said that, I wouldn't assign this a high priority unless somebody else thinks it's useful too. I've got my workaround which has the same run-time footprint in memory as if the gsinit section were not there (except the remaining "jp _gsinit" instruction in the crt).

Discussion

  • Increasing priority slightly, since this is a feature is requested by z88dk developers for integration of sdcc in z88dk, too.

    Removing the Z80 categorization, since this feature is potentially useful on other ports, too.

    Philipp

     
    • labels: 1165101 -->
    • priority: 5 --> 6
     
  • This is really a bug in the old register allocator. The new register allocator has a mechanism to avoid this problem in add_operand_conflicts_in_node() in ralloc2.cc.

    Philipp

     
  • Sorry for the previous comment. It was meant to go to bug #3441816.

    Philipp

     
  • pacomix
    pacomix
    2012-11-19

    Or in example it could be VERY useful having this for the z80 port:

    __data const unsigned char g_MyArray[] = {1,2,3,4,5,6,4,4,6,2,34};

    In order allowing the data be placed in the _DATA area instead _CODE.

     
  • Brian Ruthven
    Brian Ruthven
    2012-11-19

    The target segment is not the issue here - that's a separate bug. In a RAM-only config, it doesn't really matter whether this is in _DATA or _CODE. In a ROM+RAM config, putting this in the _CODE segment automatically enforces the "const" modifier.

    I think that littering the C code with __data is both untidy, prone to produce non-portable code, and is trying to modify the backend target assembler output. I'd much prefer a compiler option to do this. In fact, it could be argued that we should have a dedicated segment for initialised, unmodifiable code (I'd include hard-coded strings too), say _STATICDATA, which can be either in ROM (default) or placed in the _DATA segment (by means of gsinit code) with a switch. However, that's still not this enhancement request!

     
  • With the new initialization method for globals, the gsinit code size problem is gone. Still, direct initalization would be a bit more efficient than the ldir copy used now.

    Philipp

     
  • Brian Ruthven
    Brian Ruthven
    2013-08-19

    It is better since the new initialisation code went it, but direct initialisation would eliminate the need to have a separate _INITIALIZER section lying around as this still effectively doubles the global variable space needed for startup.

    I suppose it would be possible to instruct the linker to overlap the _INITIALIZED and _INITIALIZER sections in the address space but I haven't had the guts to try it myself!