[M3devel] better typing on SUBARRAY temporaries?
Rodney M. Bates
rodney_bates at lcwb.coop
Fri Jul 24 16:57:37 CEST 2015
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
More information about the M3devel
mailing list