Proposal to change ProcedureReturn

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
4RESTER
User
User
Posts: 63
Joined: Thu Aug 19, 2010 11:03 pm
Location: Uman, Ukraine

Proposal to change ProcedureReturn

Post by 4RESTER »

Example of ProcedureReturn:

Code: Select all

Procedure   BSWAP32(value.L)
!           MOV     EAX,[p.v_value]
!           BSWAP   EAX
ProcedureReturn
EndProcedure
Global      value.L = BSWAP32($12345678)
At this moment Procedurereturn produce such code:

Code: Select all

0040103F: PUSH    12345678
00401044: CALL    00401069
00401049: MOV     [DWORD DS:004030E4], EAX
...
00401069: MOV     EAX, [DWORD SS:ESP+4]
0040106D: BSWAP   EAX
0040106F: JMP     00401073   ;<=-\
00401071: XOR     EAX, EAX   ;<=- | ProcedureReturn (Jump over unused ProcedureReturn 0)
00401073: RETN    4          ;<=- /
I propose to work ProcedureReturn to produce such code:

Code: Select all

0040103F: PUSH    12345678
00401044: CALL    00401069
00401049: MOV     [DWORD DS:004030E4], EAX
...
00401069: MOV     EAX, [DWORD SS:ESP+4]
0040106D: BSWAP   EAX
REMOVE -> 0040106F: JMP     00401073        ;<- REMOVE
REMOVE -> 00401071: XOR     EAX, EAX        ;<- REMOVE
00401073: RETN    4
See ya... Image
User avatar
kenmo
Addict
Addict
Posts: 2033
Joined: Tue Dec 23, 2003 3:54 am

Re: Proposal to change ProcedureReturn

Post by kenmo »

I think the compiler would still need to convert ProcedureReturn to a JMP (since a procedure can have multiple Returns, anywhere inside it) but yes, I suppose it wouldn't hurt to remove the XOR EAX,EAX if any ProcedureReturn 'Expression' is found... (at least any UNCONDITIONAL one.)
User avatar
4RESTER
User
User
Posts: 63
Joined: Thu Aug 19, 2010 11:03 pm
Location: Uman, Ukraine

Re: Proposal to change ProcedureReturn

Post by 4RESTER »

kenmo wrote:I think the compiler would still need to convert ProcedureReturn to a JMP (since a procedure can have multiple Returns, anywhere inside it) but yes, I suppose it wouldn't hurt to remove the XOR EAX,EAX if any ProcedureReturn 'Expression' is found... (at least any UNCONDITIONAL one.)
That is what I propose.

May have already used the property returns EAX=0 by default, for example, in such cases:

Code: Select all

Procedure .................
...
If A>10
  ProcedureReturn #True
EndIf
EndProcedure
or

Code: Select all

Procedure .................
...
If A>10
  ProcedureReturn #True
EndIf
ProcedureReturn
EndProcedure
Perhaps a keyword to help keep compatibility, and still make it possible to compile the optimum.
For example:

Code: Select all

Procedure .........
ProcedureReturn AsIs
whe are "AsIs" (or somelike this) is keyword.
See ya... Image
remi_meier
Enthusiast
Enthusiast
Posts: 468
Joined: Sat Dec 20, 2003 6:19 pm
Location: Switzerland

Re: Proposal to change ProcedureReturn

Post by remi_meier »

It's not really needed that I add to this request, but
I think it might be useful to understand why it is like
it is.

The jump in your example is not necessary, of course.
It is there in case there is still some cleanup to do.
Actually, every procedurereturn will set the EAX/RAX
register, jump to the cleanup part, clean up while
preserving EAX/RAX and THEN restore the stack pointer
and return.
So what you actually want is a micro-optimization for
procedures that do not need any cleanup. That's fine
by me :mrgreen:

To illustrate what is going on, I compiled the following
code:

Code: Select all

Procedure test(a.l)
  s.s = "hi"
  ProcedureReturn 2
  ProcedureReturn
EndProcedure
which produces this commented assembler output (x64)

Code: Select all

_Procedure0:
  MOV    qword [rsp+8],rcx
  PS0=64
  XOR    rax,rax
  PUSH   rax
  PUSH   rax
  SUB    rsp,40                                                                                                                                                                                                                                                        
; s.s = "hi"
  MOV    rdx,_S1
  LEA    rcx,[rsp+40]
  CALL   SYS_FastAllocateStringFree4
; ProcedureReturn 2
  MOV    rax,2
  JMP   _EndProcedure1
; ProcedureReturn
  JMP   _EndProcedure1
; EndProcedure
  XOR    rax,rax
_EndProcedure1:
  PUSH   rax
  MOV    rcx,qword [rsp+48]
  SUB    rsp,40
  CALL   SYS_FreeString
  ADD    rsp,40
  POP    rax
  ADD    rsp,56
  RET
As you can see, every ProcedureReturn jumps to the
cleanup code. Of course this is only necessary if
there is cleanup to do and it is not needed if the
ProcedureReturn is the last statement before
EndProcedure.

I'm absolutely in favor of this request but I think Fred
has a lot of other things on his To-do list. Meanwhile
even if it breaks in the future, you may want to insert
that RETN 4 yourself. When I use risky stuff, I usually
put it within a compiler-version check:

Code: Select all

CompilerIf #PB_Compiler_Version = 460
  ;stuff
CompilerElse
  CompilerError "Check if still valid"
CompilerEndIf
If you already knew this, I apologize. It just seemed
worthwhile to mention.

greetz
Remi
Athlon64 3700+, 1024MB Ram, Radeon X1600
Post Reply