Optimization quirks

New to FreeBASIC? Post your questions here.
Post Reply
Juergen Kuehlwein
Posts: 284
Joined: Mar 07, 2018 13:59
Location: Germany

Optimization quirks

Post by Juergen Kuehlwein »

Merry Christmas everbody!


i have this little console program here, which works like a charm unless optimization is applied:

Code: Select all

'#compiler freebasic
'#compile console 32 exe /o "-gen gcc"
'#compile console 32 exe /o "-gen gcc -Wc -O3"


'***********************************************************************************************
'***********************************************************************************************


private sub do_copy(byval dest as any ptr, byval src as any ptr, byval count as Ulong) 
'***********************************************************************************************
' copy count bytes from src to dest
'***********************************************************************************************

asm
  push ecx

  mov edi, [dest]                                     'destination
  mov esi, [src]                                      'source
  mov ecx, [count]                                    '# of bytes to copy

  shr ecx, 2                                          '/4 -> # of dwords to copy
  cld
  
  rep movsd                                           'copy dwords

  mov ecx, [count]
  and ecx, 3                                          'mod 4

  rep movsb                                           'copy remaining bytes
  
  pop ecx
end asm


end sub


'***********************************************************************************************


function fb_main as long
'***********************************************************************************************
' main
'***********************************************************************************************
dim s  as string = "123456789"
dim s1 as string 


  s1 = space(len(s))

  do_copy(strptr(s1), strptr(s), len(s))
  
  print s
  print s1


  sleep


  function = 0
  
  
end function


'***********************************************************************************************
  
  
end fb_main  
  
  
'***********************************************************************************************
'***********************************************************************************************
'***********************************************************************************************
It does nothing useful except for demonstrating my problem. The sub "do_copy" is written in assembler and will be used in another application for copying data from one place to another with utmost speed. Basically this works, but as soon as optimization is applied (-Wc -o1/2/3) - it´s optimized to death. The code crashes at:

Code: Select all

rep movsd 
ESI or EDI hold incorrect values then. This happens only with the "-Wc o..." switch without it, it runs as expected.


How can i have gcc optimization without this fatal side effect? In other words, how can i prevent optimization in special places and have it everywhere else? Is there a special coding style or meta statement ensuring certain code sequences to remain untouched?


Thanks


JK
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

Re: Optimization quirks

Post by srvaldez »

hello Juergen Kuehlwein
I tested with FreeBASIC-1.06.0-win32 -gen gcc -Wc -O3
with gcc version 7.3.0 OK
with gcc version 8.1.0 OK
with gcc version 5.2.0 not OK
once I found the gcc version that would fail, then I tried different optimization options
-gen gcc -Wc -Ofast not OK
-gen gcc -Wc -Os OK

I am not aware of a method to turn optimization on/off in FB, in gcc you can https://gcc.gnu.org/onlinedocs/gcc-4.5. ... agmas.html
#pragma GCC push_options
#pragma GCC optimize ("O0")
code not optimized
#pragma GCC pop_options
restore optimization

here's a very crude/naive attempt
note: in your case, use -asm intel instead of -asm att
viewtopic.php?p=233690#p233690
viewtopic.php?p=233886#p233886

in case you are interested in FBwin with gcc-8.1.0 see http://users.freebasic-portal.de/stw/builds/_custom/
Juergen Kuehlwein
Posts: 284
Joined: Mar 07, 2018 13:59
Location: Germany

Re: Optimization quirks

Post by Juergen Kuehlwein »

srvaldez,


thanks for your reply. So this is definitely a bug in gcc, which has been fixed in later versions. I want it to be independent of gcc´s version and a two step compilation as you proposed is doable but not an option for me either.

After having a closer look at the disassembly i can see that optimization removes the call to do_copy and inserts the code directly without building an EBP based stack frame, so a "push" or "pop" inside the code changes the stack pointer. As a result the wrong data is copied into ESI, EDI and ECX. It seems that removing "push ecx" and "pop ecx" in do_copy does the trick.


But i have still another question: following the links you posted i stumbled over temporary labels. A concept, which come in handy sometimes. But when i code

Code: Select all

0:
  ...
  test ecx, ecx
  jz 0f
  ...
0:  
  ... 
i keep getting "Error: missing or invalid displacement expression `0f'", while "jz 0b" works. Why is that ?


Thanks


JK
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

Re: Optimization quirks

Post by srvaldez »

I am no expert, but using the same local label twice in the same asm block looks wrong to me.
D.J.Peters
Posts: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Optimization quirks

Post by D.J.Peters »

The -O3 or max isn't a everyday optimizations level.
Use only -O3 or above if you can control the result of all functions often not possible for large projects.
I compiled and used 8 physics engines in the past (ODE, BULLET, PHYSICS, TOKAMAK, TRUEAXIS, SED ...)

ALL and I mean ALL failed with -O3 and ALL worked fine with -O2.

failed means wrong contact information's after collision or a wrong behavior of the physics solver in general.

Joshy
srvaldez
Posts: 3379
Joined: Sep 25, 2005 21:54

Re: Optimization quirks

Post by srvaldez »

I find that for some reason -Os works when others don't
GNU compilers documentation wrote: -Os
Optimize for size. -Os enables all -O2 optimizations except those that often increase code size:

-falign-functions -falign-jumps
-falign-labels -falign-loops
-fprefetch-loop-arrays -freorder-blocks-algorithm=stc
It also enables -finline-functions, causes the compiler to tune for code size rather than execution speed, and performs further optimizations designed to reduce code size.
sean_vn
Posts: 283
Joined: Aug 06, 2012 8:26

Re: Optimization quirks

Post by sean_vn »

There are no bugs in gcc. The bug is people assuming overflows etc are valid c code when they are not. The c compiler knows you will never overflow an integer operation, hence it can assume the carry flag is clear at the end of that operation.
Should you do 2's complement arithmetic where overflows happen all the time of course the program will not execute as expected with optimizations though it may function without optimizations.
That's why FB should have its own emitter and forget about gcc etc.
Post Reply