[M3devel] better typing on SUBARRAY temporaries?

Rodney M. Bates rodney_bates at lcwb.coop
Thu Jul 30 16:16:58 CEST 2015


I'm all for having a better IR in cm3.  I've had a few serious frustrations from lack of
sufficient information in it.  But, if we touch it at all, I really want to try very hard
to think of and do everything we are likely to want in the foreseeable future.  Any
change is painful.  There are somewhere in the neighborhood of 8 or so files that have
to reflect the change.  Also, it requires atomic update to both the front end and m3cc,
which then creates bootstrap issues that have to be handled very carefully.  Jay, your
recent changes to the build process help.  But I want to avoid changing it more than
once if we can possibly avoid it.  AFAIK, m3cc is the only one that ends up a separate
executable.

And when we do it, change the version number, for better mismatch messages.  Also,
it would be the best time to add a magic number, as Elmar was wanting.

One place I encountered was in trying to get better error messages from m3linker, etc.
We get stuff like (paraphrasing from memory) "Error: missing type _t187630885".  Need
I say more?  In trying to make these helpful, I ran up against lack of information.
I remember being able to make slight improvement in one message, but that was it,
without IR changes.

Then there are also some type info deficiencies for generating debug info.  I am
remembering something about inability to connect a procedure type to procedures
that match it, or something.

On 07/29/2015 07:07 PM, Jay K wrote:
> As part of fixing this, I want M3CG_Ops.i3
>
> declare_temp (s: ByteSize;  a: Alignment;  t: Type;
>                in_memory: BOOLEAN): Var;
>
>
> to accept an optional m3t: TypeUID which can be either default to M3ID.NoID, if
> that syntax is allowed, or all existing calls can initially pass M3ID.NoID.
>
>
> The use in OpenArrayType.DeclareTemp will then be changed to something else.
> DeclareTemp will look more like OpenArrayType.Compiler.
>
>
> And, something will be done for jmpbufs, such having them be named and passing that name along
> somewhere. Or giving them a special uid, or even their own special CG.Type?
>
>
> And then, every use of CG.Type.Struct must come along with a TypeUID.
>
>
> ok?
>
> The C backend will/should actually be able notice the name of the jmpbuf type and substitute
> in.. #include <setjmp.h> jmpbuf.
>
> Other backends should  substitute in the alloca use.
>
> Or, it will be an internal parameter to the frontend for it to do the alloca transformation.
>
> But this is getting ahead of things.
>
> First -- change declare_temp to accept a TypeUID ok?
>
>
>
>   - Jay
>
>
>  > Date: Fri, 24 Jul 2015 09:57:37 -0500
>  > From: rodney_bates at lcwb.coop
>  > To: jay.krell at cornell.edu; m3devel at elegosoft.com; m3devel at elegosoft.com
>  > Subject: Re: [M3devel] better typing on SUBARRAY temporaries?
>  >
>  >
>  >
>  > On 07/24/2015 03:57 AM, Jay K wrote:
>  > > I model this in C like:
>  > >
>  > >
>  > > M3C.m3:
>  > > print(self, "/*declare_open_array*/typedef struct {");
>  >
>  > Presumably, this comment means you have some way of knowing, in M3C, that this is an open array?
>  >
>  > > print(self, element_type.text);
>  > > print(self, "* _elts; CARDINAL _size");
>  > > IF bit_size > Target.Integer.size * 2 THEN
>  > > print(self, "s[");
>  > > print(self, IntToDec((bit_size - Target.Integer.size) DIV Target.Integer.size));
>  > > print(self, "]");
>  > > END;
>  > >
>  > >
>  > > that is..and this i stinky that I get the struct "size",
>  > >
>  > >
>  > > size == 2 * sizeof(integer):
>  > >
>  > >
>  > > struct {
>  > > T* elements
>  > > size_t size;
>  > > }
>  > >
>  > >
>  > > else:
>  > > N = size - sizeof(INTEGER) / sizeof(INTEGER)
>  > > T ** elements; // where the number of star is N
>  >
>  > I would not do pointer to pointer to pointer ... here. Just "T* elements", regardless
>  > of the number of open dimensions. As I understand them, C's language-supported
>  > multidimensional arrays are like Modula3 multidimensional _fixed_ arrays, i.e.,
>  > the language does the multi-subscript address arithmetic, which means the type
>  > system needs to provide a static element size of each dimension. And that,
>  > except for the innermost, depends on the element count of the next inner
>  > dimension, which is not static here.
>  >
>  > So, the multiple dimensions are essentially flattened into one, and access to A[I,J,K]
>  > is lowered by the front end into explicit address arithmetic into the flattened
>  > array, using the values in the shape. Something like A[I*Shape[0]+J*Shape[1]+K]
>  >
>  > > size_t sizes[N]
>  > >
>  > >
>  > > It is kind of lame that the frontend just gives the overall size
>  > > and the backend is just left to assume the layout like that.
>  >
>  > If you know in M3C that it's an open array, you can infer what the layout is.
>  > But yes, it's kind of lame. This is just another of the several places we have
>  > seen that the front end has lowered things too far, and you have to
>  > You know it's generated by code in OpenArray.m3, and you know the general dope layout,
>  > and open dimension count, so you can generate an appropriate type.
>  >
>  >
>  > >
>  > > Really, the frontend should declare a type "pointer to pointer to pointer" with
>  > > the right "depth", and then a record with that pointer and a size or fixed size array of sizes.
>  > >
>  > >
>  > > Again, really ugly how it works now where backend is just given a size and can only
>  > > assume the layout.
>  > >
>  > > I don't know what a "dope vector" is. A value used as an initializer?
>  > >
>  >
>  > This is a very old and rather uninformative term for any block of stuff stored at runtime
>  > that describes some source programmer's real data and how to access it. The only alternative
>  > term I can think of would be "metadata", although that is rather overgeneral, and is usually
>  > used with quite different specific meanings. But it is data describing data.
>  >
>  > >
>  > > It is even worse for subarray. In this case we aren't even told it is an open array, just
>  > > some random struct with a size. That is what I first want to fix. It should declare an open array,
>  > > assuming they do have the same layout, which I think they do.
>  > >
>  >
>  > What you really need to know is that it's an open array, of which subarray is a subcategory.
>  > In our implementation, all open array values have the same dope. E.g., look for the case where
>  > a fixed array actual parameter is passed to an open array formal.
>  >
>  > >
>  > > subarray temporaries and jmpbufs are I believe the only place the frontend passes so little
>  > > type information.
>  > >
>  > >
>  > > For jmpbufs I'm hoping to notice their name, and, unfortunately expensive, replace them
>  > > with #include <setjmp.h> and jmpbuf, instead of just a struct with an array of bytes.
>  > >
>  > >
>  > >
>  > >
>  > > - Jay
>  > >
>  > >
>  > > > Date: Wed, 22 Jul 2015 19:30:12 -0500
>  > > > From: rodney_bates at lcwb.coop
>  > > > To: m3devel at elegosoft.com
>  > > > Subject: Re: [M3devel] better typing on SUBARRAY temporaries?
>  > > >
>  > > > I'm not exactly sure what you are asking, but here is some light on what
>  > > > you are seeing. These temporaries are exactly the dope the compiler uses
>  > > > to represent all open array values. First a pointer to the zeroth
>  > > > array element, then the "shape", as defined in M3 definition, 2.2.3, i.e.
>  > > > an array of element counts for each open subscript. For an open array
>  > > > parameter, this would be the machine representation of the parameter
>  > > > itself, authored in M3. (but passed by reference.) For a heap object,
>  > > > it is stored right before the elements themselves. For a SUBARRAY
>  > > > expression, it has to be a temporary. It also has to be constructed
>  > > > at the call site, as an anonymous temporary, when passing an entire fixed
>  > > > array to an open array parameter
>  > > >
>  > > > So, a good type for it might look like:
>  > > >
>  > > >
>  > > > RECORD
>  > > > Elements : REF ARRAY [0..Max, ... ,0..Max] OF ElementType
>  > > > ; Shape : ARRAY [0..OpenDepth-1] of CARDINAL
>  > > > END
>  > > >
>  > > > Max will be like the notorious TextLiteral.MaxBytes, i.e., we don't want any
>  > > > static limit here in the type of Elements, as it will be enforced dynamically,
>  > > > using Shape. But we don't want to just say REF ARRAY OF ElementType either,
>  > > > as this would mean another open array inside the dope, resulting in infinite
>  > > > recursion.
>  > > >
>  > > > On 07/22/2015 12:42 AM, Jay K wrote:
>  > > > > In the C backend I have a notion of "weak struct types" and "strong struct types".
>  > > > >
>  > > > >
>  > > > > "Strong" types have fields with types and names corresponding to the original Modula-3. i.e. they debug well.
>  > > > >
>  > > > >
>  > > > > "Weak" types have just arrays of characters (in a struct), sized/aligned to what the front end asked for. i.e. they debug poorly.
>  > > > >
>  > > > >
>  > > > >
>  > > > > Originally I had only weak types.
>  > > > > Ideally I have no weak types.
>  > > > > I'm down to very few weak types now.
>  > > > > I'd like to finish eliminating weak types.
>  > > > >
>  > > > >
>  > > > >
>  > > > > A quick investigation shows weak types come from open arrays and jmpbufs.
>  > > > > Open array temporaries from SUBARRAY specifically.
>  > > > >
>  > > > >
>  > > > >
>  > > > > Can we fix this?
>  > > > >
>  > > > >
>  > > > >
>  > > > > We have:
>  > > > > m3front/src/types/OpenArrayType.m3:
>  > > > >
>  > > > > PROCEDURE DeclareTemp (t: Type.T): CG.Var =
>  > > > > VAR
>  > > > > p := Reduce (t);
>  > > > > size := Target.Address.pack + OpenDepth (p) * Target.Integer.pack;
>  > > > > BEGIN
>  > > > > RETURN CG.Declare_temp (size, Target.Address.align,
>  > > > > CG.Type.Struct, in_memory := TRUE);
>  > > > > END DeclareTemp;
>  > > > >
>  > > > >
>  > > > > PROCEDURE Compiler (p: P) =
>  > > > > VAR size := Target.Address.pack + OpenDepth (p) * Target.Integer.pack;
>  > > > > BEGIN
>  > > > > Type.Compile (p.element);
>  > > > > CG.Declare_open_array (Type.GlobalUID(p), Type.GlobalUID(p.element), size);
>  > > > > END Compiler;
>  > > > >
>  > > > >
>  > > > > DeclareTemp is used in SUBARRAY expressions -- truly temporaries,
>  > > > > not variables authored by anyone in Modula-3.
>  > > > >
>  > > > >
>  > > > > Can this be easily fixed?
>  > > > >
>  > > > >
>  > > > > Thanks,
>  > > > > - Jay
>  > > > >
>  > > > >
>  > > > >
>  > > > > _______________________________________________
>  > > > > M3devel mailing list
>  > > > > M3devel at elegosoft.com
>  > > > > https://mail.elegosoft.com/cgi-bin/mailman/listinfo/m3devel
>  > > > >
>  > > >
>  > > > --
>  > > > Rodney Bates
>  > > > rodney.m.bates at acm.org
>  > > > _______________________________________________
>  > > > M3devel mailing list
>  > > > M3devel at elegosoft.com
>  > > > https://mail.elegosoft.com/cgi-bin/mailman/listinfo/m3devel
>  >
>  > --
>  > Rodney Bates
>  > rodney.m.bates at acm.org
>  > _______________________________________________
>  > M3devel mailing list
>  > M3devel at elegosoft.com
>  > https://mail.elegosoft.com/cgi-bin/mailman/listinfo/m3devel

-- 
Rodney Bates
rodney.m.bates at acm.org



More information about the M3devel mailing list