[M3devel] next problem (NT386GNU)

Tony Hosking hosking at cs.purdue.edu
Mon Jan 21 16:54:10 CET 2008


Surely, when using the gcc-based backend then we should make the  
backend handle it.  The front end handling it is only need for the  
integrated x86 backend.

On Jan 21, 2008, at 2:43 AM, Jay wrote:

> I haven't tested a fix but I see the problem.
>
> This function returns a struct.
> There are two struct returning calling conventions.
> In one, the backend handles it. Which includes the backend knowing  
> there is a return value and its type (or at least its size?).
> In the other, the front end handles it. In this case, the front end  
> generates passing an extra pointer parameter to the function, and  
> the function's return type is void.
>
> The NT calling conventions, all of them, are marked as front end  
> handling it. I assume that is correct, could check.
> Everything else is marked as back end handling.
>
> Now then, somewhere along the line, gcc figures out that the return  
> value isn't used here.
> The point of the function call is to see if it generates an exception.
>
> Gcc removes the function because its return value isn't used, and,  
> well, somehow it doesn't know about the exceptions here. I'll have  
> to see how "raise" is implemented. I think it's by a call to a  
> function that gets the jmpbuf from a thread local and calls  
> longjmp. (Did I mention it is very inefficient?)
>
> There are few possible fixes, but nothing completely satisfactory  
> yet in mind.
>
> One is have parse.c mark all function calls as having side affects.  
> This is easy, but overly pessimistic.
> Another is for the front end to mark struct returning functions as  
> having side affects. Better, but still overly pessimistic.
> Another is for the front end to mark any function that can raise as  
> having side affects. Getting better still. I don't know how to do  
> that but I'll look. This is still a bit overly pessimistic, since  
> what you really want to know is, not the function's side affects,  
> but whether or not it raised. If the function is inlined, the side  
> affects could be optimized away, or if there are enough callers who  
> don't care about the side affects to warrant an optimization, and  
> depending on the cost of computing the side affects, another  
> instance of the function could be made that only raises or not, but  
> no side affects otherwise. This is "advanced" optimization the sort  
> of which tends never to be implemented.
>
> I think the best option is anything that can raise is marked as  
> having side affects.
> I'll see if I can figure that out.
>
> You can figure this out by looking at m3cgcat -binary < M3File.mc >  
> 1.txt on PPC_DARWIN and NT386GNU and comparing.
>
> Maybe marking all or nearly functions as having side effects isn't  
> so bad.
> Or at least anything returning a struct. That gets parity with  
> other platforms, even if it is a bit pessimistic.
> I think I'll do that, and ignore figuring out if raise is called  
> and using that as a filter.
> The parity angle is good.
>
> The good news for all you Unix lovers :) is this bug is relatively  
> portable to Cygwin.
> True, it is specific to NT386GNU having multiple "calling  
> conventions", which no other platform has.
> Which again, jokingly, strikes at the question -- What is Posix?  
> What do you want from Cygwin?
> One thing Cygwin does NOT give you is just one calling convention,  
> alas, this calling convention business stinks. It's not even an NT  
> thing, only an NT386 thing. All the other NT platforms had/have  
> only one calling convention.
>
> You can't get far on NT386 without needing to support two calling  
> conventions.
> The "OS" uses mostly __stdcall -- callee pops -- smaller, faster.
> But anything that is varargs, such as printf -- pretty much must  
> use caller pops -- __cdecl.
> As well, __cdecl is the default, so prevalent, and used in most C  
> runtime functions.
> There is also __fastcall that uses like up to two registers for  
> parameters.
>
> I have seen a platform in which printf did the pop, and it depended  
> on the number/size of parameters matching the format string. On  
> most platforms, printf("", 1, 2, 3, 4) just does nothing, but on  
> that platform, it'd unbalance the stack and crash.
>
>  - Jay
>
> From: jayk123 at hotmail.com
> To: hosking at cs.purdue.edu
> CC: m3devel at elegosoft.com
> Subject: next problem (NT386GNU)
> Date: Mon, 21 Jan 2008 05:47:28 +0000
>
> M3File.m3
>
> PROCEDURE IsReadable (path: TEXT): BOOLEAN =
>   (* We don't really check for readablitiy, just for existence *)
>   BEGIN
>     TRY
>       EVAL FS.Status (path);    line 82
>       RETURN TRUE;
>     EXCEPT OSError.E =>
>       RETURN FALSE;
>     END;
>   END IsReadable;
>
>      -----LINE 82  -----
>  start_call_direct  p.25 0 Struct
>  load_address  v.25 0
>  pop_param  Addr
>  load   v.26 0 Addr Addr
>  pop_param  Addr
>  call_direct  p.25 Struct
>  pop   Struct
>
>
>
> I'm guessing you only see an import for the first call on purpose,  
> but I will compare with PPC_DARWIN:
>
>      -----LINE 46  -----
>  import_procedure  FS__Status 2 Struct 0 p.25
>  declare_indirect  2078421550 -2078421551
>  declare_param  _return 4 4 Addr 2078421550 F F 50 v.62
>  declare_param  p 4 4 Addr 1358456180 F F 50 v.63
>  start_call_direct  p.25 0 Struct
>  load_address  v.13 0
>  pop_param  Addr
>  load   v.14 0 Addr Addr
>  pop_param  Addr
>  call_direct  p.25 Struct
>  pop   Struct
>
>
> .globl _M3File__IsReadable
>  .def _M3File__IsReadable; .scl 2; .type 32; .endef
> _M3File__IsReadable:
>  .stabn 68,0,178,LM93-_M3File__IsReadable
> LM93:
>  pushl %ebp
>  movl %esp, %ebp
>  pushl %edi
>  pushl %esi
>  pushl %ebx
>  subl $300, %esp
> LBB15:
>  .stabn 68,0,181,LM94-_M3File__IsReadable
> LM94:
> L157:
>  movl -280(%ebp), %eax
>  andl $0, %eax
>  orl $_L_1, %eax
>  movl %eax, -280(%ebp)
>  movl -284(%ebp), %eax
>  andl $0, %eax
>  movl %eax, -284(%ebp)
>  subl $12, %esp
>  leal -288(%ebp), %eax
>  pushl %eax
>  call _RTHooks__PushEFrame
>  addl $16, %esp
>  leal -288(%ebp), %eax
>  addl $48, %eax
>  subl $12, %esp
>  pushl %eax
>  call __setjmp
>  addl $16, %esp
>  testb %al, %al
>  jne L158
>  .stabn 68,0,183,LM95-_M3File__IsReadable
> LM95:
>  movl -288(%ebp), %eax
>  subl $12, %esp
>  pushl %eax
>  call _RTHooks__PopEFrame
>  addl $16, %esp
>  movl $1, -304(%ebp)
>  jmp L159
> L158:
>  .stabn 68,0,185,LM96-_M3File__IsReadable
> LM96:
>  movl $0, -304(%ebp)
> L159:
> LBE15:
>  movl -304(%ebp), %eax
>  leal -12(%ebp), %esp
>  popl %ebx
>  popl %esi
>  popl %edi
>  leave
>  ret
>
>
> M3File.IsReadable's call to FS.Status is omitted, all files are  
> readable, even if they are not openable, therefore it "finds"  
> cm3.cfg in the current directory and then fails to open it..
>
> later..
>  ..Jay
>
> Climb to the top of the charts! Play the word scramble challenge  
> with star power. Play now!
> Shed those extra pounds with MSN and The Biggest Loser! Learn more.




More information about the M3devel mailing list