[m-dev.] pragma foreign_export_enum

Julien Fischer jfischer at opturion.com
Wed Nov 29 11:07:12 AEDT 2017


Hi Zoltan,

On Tue, 28 Nov 2017, Zoltan Somogyi wrote:

> On Tue, 28 Nov 2017 04:08:32 -0500 (EST), Julien Fischer <jfischer at opturion.com> wrote:
>>> One is extending the current algorithm that puts several adjacent enum arguments
>>> of a term into a single word to also treat {int,uint}{8,16,32} arguments as
>>> sub-word-sized entities that can be packed into a single 64 bit word.
>>> (Mutatis mutandis for 32 bit platforms.)
>>
>> I would like to propose a fifth (somewhat related to the first): records
>> that are really vectors of fixed size integer types, for example:
>>
>>     :- type foo ---> foo(uint32, uint32, uint32, uint32).
>>
>>     :- type ipv4_addr ---> ipv4_addr(uint8, uint8, uint8, uint8).
>>
>> should (in C grades at least) be packed into a word if they will fit, or
>> represented as an array of the fixed size integer type.
>
> Throughout this conversion, I will be assuming a 64 bit word size.
>
> I don't really see any distinction between my first (which is actually Peter's)
> and your first example of the fifth. When the compiler packs sub-word-sized fields
> into words, it doesn't stop after one word. So once we change the compiler to pack
> fixed size integer fields the way it already packs enum fields (scheme 1), values of
> type foo will be represented as pointers to a two-word cell on the heap, exactly
> the same as with your scheme 5. Did I misunderstand something?

I suspect any misunderstanding was on my end.  The distinction between
case 1 and case 5 is that because all the fields in the type are uniform
I should ideally be able to access them in C as an array of uint8_ts
etc.  What I would like here is to be a be to use structured
representation in Mercury, but be able to pass these same values
directly to C APIs with minimum (preferably no) intermediate
transformations.

I have a number of use cases in mind, so I might work through them a bit
and post some examples.

> For your second example, I think you are proposing that if all the arguments
> *do* fit into a single word, then we should get rid of the pointer and replace it
> with that word. I think that is a very good idea.
>
>> Additionally,
>> there should be a well defined mechansim for accessing the fields of
>> those types from foreign language code.  For C grades, the fact that
>> the word size may vary is a bit of a complication, but I think we could
>> arrange (perhaps via an additional pragma) for the compiler to generate
>> a macro that always returns a pointer to an array of fixed size integer
>> types regardless of whether the machine uses 32- or 64-bit words.
>
> I think that this is also a good idea, but I am pretty sure it should be
> a part of a more comprehensive approach.

Absolutely.

> For example, when called for
> either via pragma or via a compiler option, we could put into a header file
> two macros per field, which could be used like this:
>
> cur_value_of_field_n = get_foo_field_n(cur_value_of_foo);
> next_value_of_foo = set_foo_field_n(cur_value_of_foo, next_value_of_field);
>
> In the naive version, the set macros would allocate a new heap cell
> if necessary, which would make sequences of assignments to several fields
> wasteful, but we could also generate a macro that creates a new value
> from the values of *all* the fields at once. Programmers could use that
> to avoid the waste.

At one point we discussed adding an additional pragma that would cause
the compiler to generate a set of macros that defined operations along
the lines of the MR_list_* for arbitrary discriminated union types.
I'll have a hunt around on the mailing list and see if I can find it.

Julien.


More information about the developers mailing list