[M3devel] a "need" for multi-pass m3cg (or different order of calls)

Antony Hosking hosking at cs.purdue.edu
Fri Sep 7 22:10:19 CEST 2012


Sorry, I should have read more closely.  You are right.
Yes, I do believe that when generating C code you will need multiple passes to accumulate stuff to be dumped out together.
For example, I assume that to handle nested functions that you will construct a local "frame" struct for the function, containing a pointer to it’s outer scope frame struct plus all the local variables having "up_level==true".  There is no other way to do static chains portably in C.  A pointer to this frame struct will serve as the static link to inner-scope functions.


On Sep 6, 2012, at 10:23 PM, Jay K <jay.krell at cornell.edu> wrote:

> I'm not really suggesting any change to any existing code..
>  
> 
> Though, the frontend, I gather, is already multi-pass,
> so it might be nice if it did things in an order more
> convenient for backends.
> e.g. it'd be nice if all the import_procedure calls came in before any begin_procedure;
> as it stands, many come in early, and then more come in in the middle of code.
>  
> 
> I'm motivating that my C/C++ generating backend could
> benefit from internally having multiple passes.
>  
> 
> Which might be convenient to implement via a general
> mechanism for combining multiple "partial" passes.
>  
>  
> Such mechanism would naturally "temporarily persist"
> a faithful m3cg representation in memory.
> Very similar to the existing temporary binary files
> we feed to parse.c, but without all the encoding for
> compactness. i.e. an array of records
>  
>  
> I guess I'll still try to ignore this matter for now.
> I'm getting by with one pass that generates invalid C++ but valid C.
>  
>  
> Possibly I can provide a "nicely reordering m3cg"
> that buffers it all up and then plays it back
> in a slightly better order, that is more amenable
> to a simple implementation, e.g. again getting
> all the import_procedure calls in before any begin_procedure.
>  
> 
> Moving all the init_* calls to near the start instead of near the end.
> etc.
>  
>  
> i.e. I'm not really sure multiple passes are needed, it's just that
> the current ordering is kind of surprising sometimes.
>  
>  
> 
>  - Jay
> Subject: Re: [M3devel] a "need" for multi-pass m3cg (or different order of calls)
> From: hosking at cs.purdue.edu
> Date: Thu, 6 Sep 2012 17:13:14 -0400
> CC: m3devel at elegosoft.com
> To: jay.krell at cornell.edu
> 
> I’ll respond to this in more detail, but briefly, I object strongly to a multipass m3cg.  If you need multiple passes then you probably need a different internal representation (just like m3cg has a different internal representation).  M3CG is a simple single-pass linear representation of a program.  If you need multiple passes to understand it then that is your problem.  I imagine that any backend will itself need to be multipass anyway (if it is to do something useful).  I think your C backend should be multipass too.  It certainly will need to read M3CG IR and import it into some reasonable internal representation. This is exactly the strategy I am taking with M3CG to LLVM IR.  I will have some minor tweaks to M3CG just to lift its level of abstraction slightly (to better communicate typed indexing of arrays and fields, for example).  But I see no need to make M3CG do any more heavy lifting.
> 
> On Sep 6, 2012, at 4:40 AM, Jay K <jay.krell at cornell.edu> wrote:
> 
> /* The following is legal C but not C++: */
> 
> 
> struct Foo_t;
> typedef struct Foo_t Foo_t;
> static struct Foo_t Foo; /* illegal C++; C forward/tentative definition */
> 
> int F1(void) { return *(int*)&Foo; }
> 
> struct Foo_t { int i; };
> static Foo_t Foo = { 123 };
> 
> 
> This is a reason that either
> 1) I "need" to make M3C.m3 "multi pass"
> 2) or at least buffer everything in memory
> in multiple pieces and then concat at the end
> 
> 
>   I could also make it less efficient:  
> 
> 
>   struct Foo_t; /* segment */ 
>   typedef struct Foo_t Foo_t;  
>   static struct Foo_t * /*const*/ Foo;  
> 
> 
>   int F1(void) { return *(int*)&Foo; }  
> 
> 
>   struct Foo_t { int i; };
>   static Foo_t _Foo = { 123 };  
>   static Foo_t* /*const*/ Foo = &_Foo;
> 
> But that seems unfortunate.
> 
> 
> I will want to generate C++ at some point, for efficient portable exception
> handling. But that comes later.
> 
> 
> Also later, the C code needs a reordering in order to refer to fields in "segments".
> 
> 
>  - Jay

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20120907/abad8491/attachment-0002.html>


More information about the M3devel mailing list