Watch, Follow, &
Connect with Us

Please visit our new home
community.embarcadero.com.


Welcome, Guest
Guest Settings
Help

Thread: XE8: code generator question (32 bits)


This question is not answered. Helpful answers available: 2. Correct answers available: 1.


Permlink Replies: 2 - Last Post: Nov 23, 2015 8:03 AM Last Post By: Jan Dijkstra
Jan Dijkstra

Posts: 206
Registered: 11/4/99
XE8: code generator question (32 bits)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 23, 2015 3:09 AM
Currently, I have two little routines.

void __fastcall iSwap (__int64 &first, __int64 &second)
{
  __int64 temp = first;
  first  = second;
  second = temp;
}
 
void __fastcall dSwap (double &first, double &second)
{
  double temp = first;
  first  = second;
  second = temp;
}

Both of these routines do exactly the same thing. They both operate on data fields of exactly the same size (8 bytes). And yet, the code generated is not exactly the same. Here is the code for each of them
@@licMath@iSwap$qqrrjt1	proc	near
@@@licMath@iSwap$qqrrjt1 equ @@licMath@iSwap$qqrrjt1
?live1@3440:
 ;	
 ;	void __fastcall iSwap (__int64 &first, __int64 &second)
 ;	
	?debug L 500
@356:
	mov       ecx,eax
	push      ebx
	add       esp,-8
	mov       ebx,edx
 ;	
 ;	{
 ;	  __int64 temp = first;
 ;	
	?debug L 502
?live1@3456: ; ECX = first, EBX = second
	mov       eax,dword ptr [ecx]
	mov       dword ptr [esp],eax
	mov       eax,dword ptr [ecx+4]
	mov       dword ptr [esp+4],eax
 ;	
 ;	  first  = second;
 ;	
	?debug L 503
	mov       edx,dword ptr [ebx]
	mov       dword ptr [ecx],edx
	mov       edx,dword ptr [ebx+4]
	mov       dword ptr [ecx+4],edx
 ;	
 ;	  second = temp;
 ;	
	?debug L 504
?live1@3488: ; EBX = second
	mov       ecx,dword ptr [esp]
	mov       dword ptr [ebx],ecx
	mov       ecx,dword ptr [esp+4]
	mov       dword ptr [ebx+4],ecx
 ;	
 ;	}
 ;	
	?debug L 505
?live1@3504: ; 
@357:
	pop       ecx
	pop       edx
	pop       ebx
	ret 
	?debug L 0
@@licMath@iSwap$qqrrjt1	endp
 
 
 
@@licMath@dSwap$qqrrdt1	proc	near
@@@licMath@dSwap$qqrrdt1 equ @@licMath@dSwap$qqrrdt1
?live1@4416:
 ;	
 ;	void __fastcall dSwap (double &first, double &second)
 ;	
	?debug L 685
@426:
	add       esp,-8
 ;	
 ;	{
 ;	  double temp = first;
 ;	
	?debug L 687
?live1@4432: ; EAX = first, EDX = second
	mov       ecx,dword ptr [eax]
	mov       dword ptr [esp],ecx
	mov       ecx,dword ptr [eax+4]
	mov       dword ptr [esp+4],ecx
 ;
 ;	  first  = second;
 ;	
	?debug L 688
	mov       ecx,dword ptr [edx]
	mov       dword ptr [eax],ecx
	mov       ecx,dword ptr [edx+4]
	mov       dword ptr [eax+4],ecx
 ;	
 ;	  second = temp;
 ;	
	?debug L 689
?live1@4464: ; EDX = second
	mov       eax,dword ptr [esp]
	mov       dword ptr [edx],eax
	mov       eax,dword ptr [esp+4]
	mov       dword ptr [edx+4],eax
 ;	
 ;	}
 ;	
	?debug L 690
?live1@4480: ; 
@427:
	pop       ecx
	pop       edx
	ret 
	?debug L 0
@@licMath@dSwap$qqrrdt1	endp

As can be seen, the second version (for the double data type) is more efficient. It doesn't use the EBX register at all, and simply uses the ECX register as scratch register for all assignment statements that need a scratch register. Which does not happen in the __int64 version.

The question I have is why. Why two different code templates for what, at the assembly language level, is basically the same thing. Moving around a couple of 8 byte memory blocks.

The extra overhead of unneeded assembly instructions doesn't seem much, but it does all add up for a routine that can be called many times. As you might guess, the swap routine will be used in sorting algorithms.
Sean Hoffman

Posts: 126
Registered: 3/28/99
Re: XE8: code generator question (32 bits)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 23, 2015 6:12 AM   in response to: Jan Dijkstra in response to: Jan Dijkstra
Surprising that neither of those takes advantage of the XCHG instruction.
Jan Dijkstra

Posts: 206
Registered: 11/4/99
Re: XE8: code generator question (32 bits)  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Nov 23, 2015 8:03 AM   in response to: Sean Hoffman in response to: Sean Hoffman
Sean Hoffman wrote:
Surprising that neither of those takes advantage of the XCHG instruction.

No, that's not surprising. That could only have happened if the parser is able to deduce from my 3 statements in the function that I'm actually swapping the first and second parameter's values. And I doubt the parser is able to deduce that ;)

What it sees is 3 assignments, and it generates code for each of these, while tracking which registers hold which value from statement to statement in the function.
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02