Sign in Join

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

Mailing lists / fpc-devel / 2006-08

Bug: compilation loop in 2.0.2 when using -So

21 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

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

Konstantin Münning

Hello!

I tried again to use 2.0.x compiler (am still using mostly 1.0.10) and encountered a bug which seems to be unknown (according to bugtracker and mailing list) yet.

When compiling a unit which uses some RTL unit (I tried only a few) in its IMPLEMENTATION section with -So, the unit is compiled over and over again. Here sample files:

----------
UNIT bug;
 INTERFACE
 IMPLEMENTATION
  USES Baseunix;
END.
----------
UNIT ok;
 INTERFACE
  USES Baseunix;
 IMPLEMENTATION
END.
----------

to be compiled with "fpc -So bug". Using linux or syscall does the same so it is connected to -So flag. I tried 2.0.0 and there this bug is not present. When compiling it with no options (like "fpc bug") it is compiled OK. When the RTL unit is used in interface section or a program is compiled it seems to be OK as well (see unit ok).

Should I add this bug to bugtracker? What are the chances this to be fixed in 2.0.4 if it isn't already?

Have a nice day,

Konstantin Münning

Reply by email

Tomas Hajny
to Konstantin Münning

Konstantin MĂźnning wrote:

Hello,

I tried again to use 2.0.x compiler (am still using mostly 1.0.10) and encountered a bug which seems to be unknown (according to bugtracker and mailing list) yet.

.
.

Should I add this bug to bugtracker? What are the chances this to be fixed in 2.0.4 if it isn't already?

I can't check whether it has been fixed in the meantime or not at the moment - you could possibly check it yourself using the published release candidates available from our FTP server (/pub/fpc/beta/2.0.4-rc3/). If it's still there, you're certainly welcome to add report to our bug tracker. Unfortunately, if it hasn't been fixed yet, getting it to 2.0.4 wouldn't be possible any more.

Tomas

Reply by email

Jonas Maebe
to Konstantin Münning: Hello! I tried again to use 2.0.x compiler (am still using mostly 1.0.10) and encountered…
Konstantin Münning wrote 9 lines
I tried again to use 2.0.x compiler (am still using mostly 1.0.10) and encountered a bug which seems to be unknown (according to bugtracker and mailing list) yet. When compiling a unit which uses some RTL unit (I tried only a few) in its IMPLEMENTATION section with -So, the unit is compiled over and over again.

This is a known bug and it has been fixed.

Jonas

Reply by email

Konstantin Münning
to Jonas Maebe
Jonas Maebe wrote 12 lines
On 17 aug 2006, at 17:49, Konstantin Münning wrote: > I tried again to use 2.0.x compiler (am still using mostly 1.0.10) and > encountered a bug which seems to be unknown (according to bugtracker and > mailing list) yet. > > When compiling a unit which uses some RTL unit (I tried only a few) in > its IMPLEMENTATION section with -So, the unit is compiled over and over > again. This is a known bug and it has been fixed.

I'm just testing 2.0.4-rc3 and yes, it's fixed there :-).

There are some other inconsistencies to previous versions of FPC and Borland Pascal like assembler syntax and pointer addition (inc(Pointer,LongInt) does not work anymore).

If someone is interested I can post details. It seems possible to work around them.

Last thing - size. Program tested results with 1.0.10 in 354KB and with 2.0.4-rc3 in 515KB. Both with default optimization options and no debug info. Tried -Og but result was almost the same. Is this the final state or are improvements to be expected?

Konstantin

Reply by email

Jonas Maebe
to Konstantin Münning
Konstantin Münning wrote
There are some other inconsistencies to previous versions of FPC and Borland Pascal like assembler syntax and pointer addition (inc(Pointer,LongInt) does not work anymore).

Please (as always) post a test program, because it works file for me with 2.0.4-rc3.

If someone is interested I can post details. It seems possible to work around them.

Always post a compilable program which demonstrates the problem if you want bugs to be fixed, preferably in the bug tracker at http:// www.freepascal.org/mantis.

Show quoted text 7 lines
Last thing - size. Program tested results with 1.0.10 in 354KB and with 2.0.4-rc3 in 515KB. Both with default optimization options and no debug info. Tried -Og but result was almost the same. Is this the final state or are improvements to be expected?

Definitely final for 2.0.4-rc3. Make sure you also use -CX -XX to turn on smartlinking.

It may become bigger or smaller in the future depending on a number of factors, including but not limited to optimizer improvements, (smart)linking improvements, routines added to the system unit which are referenced from the initialization section, effort required to investigate in detail why things became bigger vs the impact this has for most people, the fact whether someone who actually cares about executable file size performs said investigations, and the phase of the moon.

Jonas

Reply by email

Daniël Mantione
to Konstantin Münning: I'm just testing 2.0.4-rc3 and yes, it's fixed there :-). There are some other…

Op Thu, 17 Aug 2006, schreef Konstantin Münning:

Show quoted text 15 lines
Jonas Maebe wrote: I'm just testing 2.0.4-rc3 and yes, it's fixed there :-). There are some other inconsistencies to previous versions of FPC and Borland Pascal like assembler syntax and pointer addition (inc(Pointer,LongInt) does not work anymore). If someone is interested I can post details. It seems possible to work around them. Last thing - size. Program tested results with 1.0.10 in 354KB and with 2.0.4-rc3 in 515KB. Both with default optimization options and no debug info. Tried -Og but result was almost the same. Is this the final state or are improvements to be expected?

Sounds like you didn't use smart linking. Of course the total amount of code in the RTL will only grow, so if you want small executables, always use smartlinking to remove the code that you don't use. (Programs will be a bit larger in 2.0, but not that much.)

Daniël

Reply by email

Tomas Hajny
to Jonas Maebe: Please (as always) post a test program, because it works file for me with 2.0.4-rc3.…
Jonas Maebe wrote 8 lines
On 17 aug 2006, at 21:40, Konstantin MĂźnning wrote: > There are some other inconsistencies to previous versions of FPC and > Borland Pascal like assembler syntax and pointer addition > (inc(Pointer,LongInt) does not work anymore). Please (as always) post a test program, because it works file for me with 2.0.4-rc3.

I guess this might be related to the point recently added to Issues_2.0.4 page in Wiki (note that it still requires $mode tp).

Tomas

Reply by email

Konstantin Münning
to Tomas Hajny
Tomas Hajny wrote 11 lines
Jonas Maebe wrote: > On 17 aug 2006, at 21:40, Konstantin MĂźnning wrote: > >> There are some other inconsistencies to previous versions of FPC and >> Borland Pascal like assembler syntax and pointer addition >> (inc(Pointer,LongInt) does not work anymore). > Please (as always) post a test program, because it works file for me > with 2.0.4-rc3. I guess this might be related to the point recently added to Issues_2.0.4 page in Wiki (note that it still requires $mode tp).

Yes, my inc(Pointer,LongInt) is the same like point 7 of Issues with 2.0.4-rc3 in Wiki. I haven't tried without $mode tp as my program requires it.

I will post some assembler examples shortly.

Konstantin

Reply by email

Konstantin Münning
to Jonas Maebe: Please (as always) post a test program, because it works file for me with 2.0.4-rc3.…
Jonas Maebe wrote 24 lines
On 17 aug 2006, at 21:40, Konstantin Münning wrote: > There are some other inconsistencies to previous versions of FPC and > Borland Pascal like assembler syntax and pointer addition > (inc(Pointer,LongInt) does not work anymore). Please (as always) post a test program, because it works file for me with 2.0.4-rc3. > If someone is interested I can post details. It seems possible to work > around them. Always post a compilable program which demonstrates the problem if you want bugs to be fixed, preferably in the bug tracker at http://www.freepascal.org/mantis. > Last thing - size. Program tested results with 1.0.10 in 354KB and with > 2.0.4-rc3 in 515KB. Both with default optimization options and no debug > info. Tried -Og but result was almost the same. Is this the final state > or are improvements to be expected? Definitely final for 2.0.4-rc3. Make sure you also use -CX -XX to turn on smartlinking.

As I remember some problems with smartlinking I left it to default behaviour. Maybe my information was too old. Using -CX and -XX it's much better - with 1.0.10 it's 238KB and with 2.0.4-rc3 it's 277KB. Still got a bit bigger but that's sometimes in the nature of improvement :-).

What is the current general advice about smartlinking? Are there any concerns left for using it?

Show quoted text 8 lines
It may become bigger or smaller in the future depending on a number of factors, including but not limited to optimizer improvements, (smart)linking improvements, routines added to the system unit which are referenced from the initialization section, effort required to investigate in detail why things became bigger vs the impact this has for most people, the fact whether someone who actually cares about executable file size performs said investigations, and the phase of the moon.

;-)

Konstantin

Reply by email

Konstantin Münning
to Jonas Maebe: Please (as always) post a test program, because it works file for me with 2.0.4-rc3.…
Jonas Maebe wrote 9 lines
On 17 aug 2006, at 21:40, Konstantin Münning wrote: > There are some other inconsistencies to previous versions of FPC and > Borland Pascal like assembler syntax and pointer addition > (inc(Pointer,LongInt) does not work anymore). Please (as always) post a test program, because it works file for me with 2.0.4-rc3.

Here to demonstrate assembler problem:

PROGRAM Original;
{$ASMMODE Intel}
 PROCEDURE Test(p:Pointer;l:LongInt;w:Word;b:Byte);ASSEMBLER;
  ASM
   mov eax,[p]
   mov eax,[l]
   mov ax,[w]
   mov al,[b]
  END;
BEGIN
END.

This program is like the code I'm using which works with fpc 1.0.10 and BP (BP is 16 bit only so without eax). FPC 2.0.x complains on the mov ax,[w] with the error(s):

original.pas(7,13) Error: Asm: 16 Bit references not supported
original.pas(7,13) Error: Asm: Invalid effective address

Modifying like this fixes this:

PROGRAM Modified;
{$ASMMODE Intel}
 PROCEDURE Test(p:Pointer;l:LongInt;w:Word;b:Byte);ASSEMBLER;
  ASM
   mov eax,[p]
   mov eax,[l]
   mov ax,w
   mov al,[b]
  END;
BEGIN
END.

Interestingly this works without complaints:

PROGRAM Working;
{$ASMMODE Intel}
 PROCEDURE Test;ASSEMBLER;
  VAR
   p:Pointer;
   l:LongInt;
   w:Word;
   b:Byte;
  ASM
   mov eax,[p]
   mov eax,[l]
   mov ax,[w]
   mov al,[b]
  END;
 VAR
  p:Pointer;
  l:LongInt;
  w:Word;
  b:Byte;
BEGIN
 ASM
  mov eax,[p]
  mov eax,[l]
  mov ax,[w]
  mov al,[b]
 END;
END.

Konstantin

Reply by email

Jonas Maebe
to Konstantin Münning
Konstantin Münning wrote 19 lines
PROGRAM Original; {$ASMMODE Intel} PROCEDURE Test(p:Pointer;l:LongInt;w:Word;b:Byte);ASSEMBLER; ASM mov eax,[p] mov eax,[l] mov ax,[w] mov al,[b] END; BEGIN END. This program is like the code I'm using which works with fpc 1.0.10 and BP (BP is 16 bit only so without eax). FPC 2.0.x complains on the mov ax,[w] with the error(s): original.pas(7,13) Error: Asm: 16 Bit references not supported original.pas(7,13) Error: Asm: Invalid effective address

That's because the default calling convention is now register instead of oldfpccall. p is now passed in eax, l in edx and w in cx. So the the compiling is complaining because the above now means "mov ax, [cx]".

Add {$calling stdcall} (or alternatively {$calling oldfpccall}, but that's not encouraged since this calling convention is FPC-specific) to you source to switch back to passing all parameters on the stack.

Jonas

Reply by email

Konstantin Münning
to Jonas Maebe
Jonas Maebe wrote 25 lines
On 18 aug 2006, at 13:36, Konstantin Münning wrote: > PROGRAM Original; > {$ASMMODE Intel} > PROCEDURE Test(p:Pointer;l:LongInt;w:Word;b:Byte);ASSEMBLER; > ASM > mov eax,[p] > mov eax,[l] > mov ax,[w] > mov al,[b] > END; > BEGIN > END. > > This program is like the code I'm using which works with fpc 1.0.10 and > BP (BP is 16 bit only so without eax). FPC 2.0.x complains on the mov > ax,[w] with the error(s): > > original.pas(7,13) Error: Asm: 16 Bit references not supported > original.pas(7,13) Error: Asm: Invalid effective address That's because the default calling convention is now register instead of oldfpccall. p is now passed in eax, l in edx and w in cx. So the the compiling is complaining because the above now means "mov ax, [cx]".

Does this mean above code is translated to

mov eax,[eax]
mov eax,[ebx]
mov ax,[cx]

? Because that would be awfully wrong! With the new calling convention it should be translated as

mov eax,eax
mov eax,ebx
mov ax,cx

Add {$calling stdcall} (or alternatively {$calling oldfpccall}, but that's not encouraged since this calling convention is FPC-specific) to you source to switch back to passing all parameters on the stack.

Is the $calling mixable? I mean would units compiled with {$calling stdcall} work with programs compiled without or with some other $calling?

Konstantin

Reply by email

Jonas Maebe
to Konstantin Münning
Konstantin Münning wrote 12 lines
> That's because the default calling convention is now register > instead of > oldfpccall. p is now passed in eax, l in edx and w in cx. So the the > compiling is complaining because the above now means "mov ax, [cx]". Does this mean above code is translated to mov eax,[eax] mov eax,[ebx] mov ax,[cx] ?

Yes.

Show quoted text 6 lines
Because that would be awfully wrong! With the new calling convention it should be translated as mov eax,eax mov eax,ebx mov ax,cx

I presume that what we do is Delphi compatible. To, it seems more like the TP/Delphi (and probably masm/tasm) behaviour of treating "[p]" and "p" as the same thing was wrong. [] means a memory reference and [p] should actually mean something like [[ebp+8]] or so if p is stored at address ebp+8 (which is an addressing mode that is not supported by the 80x86, but it is supported by e.g. the m68k).

Is the $calling mixable? I mean would units compiled with {$calling stdcall} work with programs compiled without or with some other $calling?

The calling convention of routine is saved in the ppu file of a compiled unit, so if it's called from another module (program or unit) the approrpriate calling convention will be looked up and used.

You can also specify the calling convention of an individual procedure by adding it after it, e.g.

procedure test; stdcall;
begin
  ..
end;

Jonas

Reply by email

Marco van de Voort
to Jonas Maebe
Show quoted text 6 lines
I presume that what we do is Delphi compatible. To, it seems more like the TP/Delphi (and probably masm/tasm) behaviour of treating "[p]" and "p" as the same thing was wrong. [] means a memory reference and [p] should actually mean something like [[ebp+8]] or so if p is stored at address ebp+8 (which is an addressing mode that is not supported by the 80x86, but it is supported by e.g. the m68k).

Sb (Carlo probably, since it was passcript) just remarked on IRC that the register convention is not compatible.

The registers are pushed left to right (which I verified), while Delphi does right to left. (not verified)

Reply by email

Jonas Maebe
to Marco van de Voort
Marco van de Voort wrote 14 lines
> presume that what we do is Delphi compatible. To, it seems more > like the TP/Delphi (and probably masm/tasm) behaviour of treating > "[p]" and "p" as the same thing was wrong. [] means a memory > reference and [p] should actually mean something like [[ebp+8]] or so > if p is stored at address ebp+8 (which is an addressing mode that is > not supported by the 80x86, but it is supported by e.g. the m68k). Sb (Carlo probably, since it was passcript) just remarked on IRC that the register convention is not compatible. The registers are pushed left to right (which I verified), while Delphi does right to left. (not verified)

The registers parameters contain the same values on FPC and Delphi. What's different is the order in which parameters which do not fit in registers are pushed. On FPC it's left to right, while Delphi does right to left.

Kylix example:

procedure test(a,b,c,d,e: longint);
begin
end;
begin
   test(1,2,3,4,5);
end.

Kylix generates:

0x0804d483 <PROGRAM+23>: push $0x4
0x0804d485 <PROGRAM+25>: push $0x5
0x0804d487 <PROGRAM+27>: mov $0x3,%ecx
0x0804d48c <PROGRAM+32>: mov $0x2,%edx
0x0804d491 <PROGRAM+37>: mov $0x1,%eax
0x0804d496 <PROGRAM+42>: call 0x804d41c <test>

We generate:

pushl $5
pushl $4
movl $3,%ecx
movl $2,%edx
movl $1,%eax
call P$PROGRAM_TEST$LONGINT$LONGINT$LONGINT$LONGINT$LONGINT

I don't understand the logic of what Delphi/Kylix does. The registers are loaded from left to right, yet the other parameters are pushed from right to left...

Jonas

Reply by email

Konstantin Münning
to Jonas Maebe: Yes. I presume that what we do is Delphi compatible. To, it seems more like the TP/Delphi…
Jonas Maebe wrote 30 lines
On 18 aug 2006, at 14:10, Konstantin Münning wrote: >> That's because the default calling convention is now register instead of >> oldfpccall. p is now passed in eax, l in edx and w in cx. So the the >> compiling is complaining because the above now means "mov ax, [cx]". > > Does this mean above code is translated to > > mov eax,[eax] > mov eax,[ebx] > mov ax,[cx] > > ? Yes. > Because that would be awfully wrong! With the new calling convention > it should be translated as > > mov eax,eax > mov eax,ebx > mov ax,cx I presume that what we do is Delphi compatible. To, it seems more like the TP/Delphi (and probably masm/tasm) behaviour of treating "[p]" and "p" as the same thing was wrong. [] means a memory reference and [p] should actually mean something like [[ebp+8]] or so if p is stored at address ebp+8 (which is an addressing mode that is not supported by the 80x86, but it is supported by e.g. the m68k).

As I'm not using Delphi I can't tell, but it is in fact the improval of TASM ideal mode over the MASM quirks. Yes, [] means a memory reference which is correct on first sight. All assembler labels are nothing than pointers to memory. So using move ax,[p] would mean something like mov ax,[ebp+8] which is correct whrereas mov ax,p would mean mov ax,ebp+8 or for x86 lea ax,ebp+8. I am using IDEAL TASM syntax in TASM and BP and it makes the code quite clear IMHO.

So a programmer should not need exactly to know if/when a variable is cached in a register or saved on the stack (=memory) and when referencing it the same way the same result should be expected.

Here an example where the same source code is compiled differently which should not depend on calling convention, register caching or whatsoever:

PROCEDURE Test(l:LongInt);ASSEMBLER;
 ASM
  mov eax,[l]
 END;
PROCEDURE Test;ASSEMBLER;
 VAR l:LongInt;
 ASM
  mov eax,[l]
 END;

Konstantin

Reply by email

Jonas Maebe
to Konstantin Münning: As I'm not using Delphi I can't tell, but it is in fact the improval of TASM ideal mode…
Konstantin Münning wrote
So a programmer should not need exactly to know if/when a variable is cached in a register or saved on the stack (=memory) and when referencing it the same way the same result should be expected.

A programmer actually must always be aware of how the parameters are passed, because otherwise in case of register parameters he can unknowingly overwrite some parameters while "loading" others into registers. So he almost always needs different code anyway.

Show quoted text 15 lines
Here an example where the same source code is compiled differently which should not depend on calling convention, register caching or whatsoever: PROCEDURE Test(l:LongInt);ASSEMBLER; ASM mov eax,[l] END; PROCEDURE Test;ASSEMBLER; VAR l:LongInt; ASM mov eax,[l] END;

Well, it does depend on it and it will probably not be changed, since that would break too much compatibility.

Jonas

Reply by email

Konstantin Münning
to Jonas Maebe
Jonas Maebe wrote 11 lines
On 18 aug 2006, at 14:56, Konstantin Münning wrote: > So a programmer should not need exactly to know if/when a variable is > cached in a register or saved on the stack (=memory) and when > referencing it the same way the same result should be expected. A programmer actually must always be aware of how the parameters are passed, because otherwise in case of register parameters he can unknowingly overwrite some parameters while "loading" others into registers. So he almost always needs different code anyway.

You are right, he should be aware of but when looking at the same code he shouldn't need to know the moon phase to be able to understand what it's doing today ;-).

Show quoted text 16 lines
> Here an example where the same source code is compiled differently which > should not depend on calling convention, register caching or whatsoever: > > PROCEDURE Test(l:LongInt);ASSEMBLER; > ASM > mov eax,[l] > END; > > PROCEDURE Test;ASSEMBLER; > VAR l:LongInt; > ASM > mov eax,[l] > END; Well, it does depend on it and it will probably not be changed, since that would break too much compatibility.

So there are really people using things like the first example for indirect addressing instead of mov eax,[eax] as they are aware of register usage? I'm sorry but I can't imagine some real use in this alternating behavior so it's required it to be kept and not interpreted "correctly" by the compiler.

As I don't have Delphi, can somebody check/confirm it is done this way there? Sorry that I'm not an easy believer ;-).

OK, here the next coding example which is broken since 1.0.10:

PROGRAM Test;
{$ASMMODE Intel}
{$R+}
 TYPE
  TTest=RECORD
         a,b,c:Word;
        END;
 PROCEDURE Test1(t:TTest);ASSEMBLER;
  ASM
   mov ax,[t.a]
  END;
BEGIN
END.

Which causes

test.pas(11,15) Error: Size suffix and destination or source size do not
match

Apparently the size check is done on t and not on t.a. It does not matter which register I use (eax, ax or al) nor the type of a,b,c. The code generated calculates correctly the record element size(s) so it seems to be only the check which is flawed. This error happens when the total size of TType is bigger than 4 bytes and range check is on. Without range check instead of an error a warning is displayed. I must admit that in 1.0.10 no check whatsoever was done there so this is somehow better ;-).

Konstantin

Reply by email

Tomas Hajny
to Konstantin Münning
Konstantin Münning wrote
Jonas Maebe wrote: > On 18 aug 2006, at 14:56, Konstantin Münning wrote:

.
.

Show quoted text 10 lines
>> PROCEDURE Test(l:LongInt);ASSEMBLER; >> ASM >> mov eax,[l] >> END; >> >> PROCEDURE Test;ASSEMBLER; >> VAR l:LongInt; >> ASM >> mov eax,[l] >> END;

BTW, putting the lines above into a file, adding the following four lines at the bottom:

 begin
  Test(123);
  Test;
 end.

and trying to compile (with -Mtp parameter to ensure asmmode intel) results in:
---
Free Pascal Compiler version 2.0.4-rc3 [2006/08/13] for i386 Copyright (c) 1993-2006 by Florian Klaempfl
x.pas(7,12) Error: overloaded functions have the same parameter list x.pas(16) Fatal: There were 1 errors compiling module, stopping x.pas(16) Fatal: Compilation aborted
===

I don't think this is correct...

Tomas

Reply by email

Daniël Mantione
to Tomas Hajny

Op Fri, 18 Aug 2006, schreef Tomas Hajny:

Show quoted text 11 lines
and trying to compile (with -Mtp parameter to ensure asmmode intel) results in: --- Free Pascal Compiler version 2.0.4-rc3 [2006/08/13] for i386 Copyright (c) 1993-2006 by Florian Klaempfl x.pas(7,12) Error: overloaded functions have the same parameter list x.pas(16) Fatal: There were 1 errors compiling module, stopping x.pas(16) Fatal: Compilation aborted === I don't think this is correct...

It is correct that it refuses to compile it (overloading is forbidden in TP mode), however, I'm less fond of the error message.

Daniël

Reply by email