Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2022-04

Compiler internals. Changing dynamic arrays format

4 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

denisgolovan

Hi all

I've been maintaining a set of private patches for some quite old FPC revision for some years. The idea behind those patches to ease interoperation between FPC and LuaJIT FFI by pointer tagging for dynamic arrays. For that to happen I was forced to modify "tdynarray" record (increase its size to 32 bytes and always align dynamic arrays to 32 bytes) & change some compiler internals to emit proper offset to "high" and "reference count" fields.

Bootstrapping patched compiler is quite an adventure. And that is something I'd like to straight-line and I feel that I need some piece of advice.

My first trouble is initialization of dynamic arrays with constant arrays. It looks like simply building one version of compiler just makes a build with old-style array constants and my already patched code. That leads to code/constant data format mismatches and new compiler process just crashes.

Looks vanilla makefile builds a several versions of compiler progressing to a final version. It seems that my troubles also can be solved by enabling parts of the patchset progressively. More specifically, I plan to enable array serialization code patch first in cyclelevel 1. Then build next compiler level using compiler 1 with rest code enabled to get cyclelevel 2. Cyclelevel2 build should already contain both all code changes and data constants in new format. And finally build cyclelevel3 build with cyclelevel2 compiler to complete build.

Is it the right way to go?
And if I get it right - could anyone suggest me how to enable my constants code serialization patches (via conditional defines I guess) at cyclelevel 1 and all patches at cyclelevels 2 and 3?

-- Regards,
Denis Golovan

Tomas Hajny
to denisgolovan

On 2022-04-13 00:34, denisgolovan via fpc-pascal wrote:

Hi Denis,

I've been maintaining a set of private patches for some quite old FPC revision for some years.

.
.

Show quoted text 24 lines
My first trouble is initialization of dynamic arrays with constant arrays. It looks like simply building one version of compiler just makes a build with old-style array constants and my already patched code. That leads to code/constant data format mismatches and new compiler process just crashes. Looks vanilla makefile builds a several versions of compiler progressing to a final version. It seems that my troubles also can be solved by enabling parts of the patchset progressively. More specifically, I plan to enable array serialization code patch first in cyclelevel 1. Then build next compiler level using compiler 1 with rest code enabled to get cyclelevel 2. Cyclelevel2 build should already contain both all code changes and data constants in new format. And finally build cyclelevel3 build with cyclelevel2 compiler to complete build. Is it the right way to go? And if I get it right - could anyone suggest me how to enable my constants code serialization patches (via conditional defines I guess) at cyclelevel 1 and all patches at cyclelevels 2 and 3?

Your comment about conditional defines goes in the right direction - basically:

1) Separate your changes into parts affecting the compiler behaviour (e.g. the changes impacting the compiled structures and code, etc.) from changes needed because of the changed behaviour (i.e. use of your new features within the RTL and/or the compiler, modified versions of code working with the newly / differently compiled structures, etc.).

2) Create a conditional define for your new changes - this new define would be enabled within the compiler behaviour affecting changes.

3) Make your changes resulting from the changed behaviour (either in the RTL, or in the compiler) enabled only when the new conditional define is enabled.

If you do this, you should be able to use the standard makefiles without any changes (e.g. "make compiler_cycle", etc.).

Tomas

denisgolovan
to Tomas Hajny
Show quoted text 22 lines
On 2022-04-13 00:34, denisgolovan via fpc-pascal wrote: Your comment about conditional defines goes in the right direction - basically: 1) Separate your changes into parts affecting the compiler behaviour (e.g. the changes impacting the compiled structures and code, etc.) from changes needed because of the changed behaviour (i.e. use of your new features within the RTL and/or the compiler, modified versions of code working with the newly / differently compiled structures, etc.). 2) Create a conditional define for your new changes - this new define would be enabled within the compiler behaviour affecting changes. 3) Make your changes resulting from the changed behaviour (either in the RTL, or in the compiler) enabled only when the new conditional define is enabled. If you do this, you should be able to use the standard makefiles without any changes (e.g. "make compiler_cycle", etc.). Tomas

Ok. It's good then.
I'd like to know about the actual CYCLELEVEL logic implementation details.

So far I haven't found any explicit conditional define related to cycle levels. I assume something like:

  {$IF not defined(FPC_CYCLELEVEL1) and not defined(FPC_CYCLELEVEL2) and not defined(FPC_CYCLELEVEL3)}
    // previous version compiler builds our sources
    def_system_macro('FPC_CYCLELEVEL1');
  {$ENDIF}
  {$IFDEF FPC_CYCLELEVEL1}
    // CYCLELEVEL1 compiler builds our sources
    def_system_macro('FPC_CYCLELEVEL2');
  {$ENDIF}
  {$IFDEF FPC_CYCLELEVEL2}
    // CYCLELEVEL2 compiler builds our sources
    def_system_macro('FPC_CYCLELEVEL3');
  {$ENDIF}
  {$IFDEF FPC_CYCLELEVEL3}
    // CYCLELEVEL3 compiler builds our sources
    def_system_macro('FPC_CYCLELEVEL4');
  {$ENDIF}

... somewhere in options.pas should be enough.
Or maybe there is already some existing / more reliable way?

-- Regards,
Denis Golovan

Michael Van Canneyt
to denisgolovan
denisgolovan wrote 29 lines
> On 2022-04-13 00:34, denisgolovan via fpc-pascal wrote: > Your comment about conditional defines goes in the right direction - > basically: > > 1) Separate your changes into parts affecting the compiler behaviour > (e.g. the changes impacting the compiled structures and code, etc.) from > changes needed because of the changed behaviour (i.e. use of your new > features within the RTL and/or the compiler, modified versions of code > working with the newly / differently compiled structures, etc.). > > 2) Create a conditional define for your new changes - this new define > would be enabled within the compiler behaviour affecting changes. > > 3) Make your changes resulting from the changed behaviour (either in the > RTL, or in the compiler) enabled only when the new conditional define is > enabled. > > If you do this, you should be able to use the standard makefiles without > any changes (e.g. "make compiler_cycle", etc.). > > Tomas Ok. It's good then. I'd like to know about the actual CYCLELEVEL logic implementation details. So far I haven't found any explicit conditional define related to cycle levels.

They don't exist.

Show quoted text 6 lines
I assume something like: {$IF not defined(FPC_CYCLELEVEL1) and not defined(FPC_CYCLELEVEL2) and not defined(FPC_CYCLELEVEL3)} // previous version compiler builds our sources def_system_macro('FPC_CYCLELEVEL1'); {$ENDIF}

What Tomas means is that you do your changes in

   {$IFDEF FPC_HAS_MYFEATURE}
   // Code specific to your feature
   {$ENDIF}

and in the part where all macros are defined (normally options.pas), do a

    def_system_macro('FPC_HAS_MYFEATURE');

This way, when you start with the normal compiler, your code will not be included, but the first-level compiler will, when compiling, have the FPC_HAS_MYFEATURE defined, and your feature code will be included.

Michael.