pure-c / purec

C backend for PureScript
232 stars 8 forks source link

Consider copying boxed integers and numbers #38

Closed felixSchl closed 5 years ago

felixSchl commented 5 years ago

Heap allocating boxes for integers, doubles, and chars seems very redundant when it should be cheaper to just copy around the box itself. This needs to be properly investigated.

I just found myself writing this FFI code:

PURS_FFI_FUNC_4(Control_Monad_ST_Internal_for, _lo, _hi, f, _, {
    int lo = purs_any_get_int(_lo);
    int hi = purs_any_get_int(_hi);
    for (int i = 0; i < hi; i++) {
        purs_any_app(purs_any_app(f, purs_any_int_new(i) /* ouch! */), NULL)
    }
    return NULL;
});
felixSchl commented 5 years ago

Actually, it should be possible to simply copy the purs_any_t everywhere and only take pointers to it for internal functions if needed. We can probably use a smaller type for the tag, making the cost of copying this thing around negligible (tag + union)?

felixSchl commented 5 years ago

I'd love feedback on this. I just set up the inlineCommonValues optimization pass and added as a first example inlining integer negation, but this optimization looks far from optimal:

https://github.com/pure-c/pure-c/blob/187fb7f54cbb890cfd276f72ab04186c067b92a9/src/Language/PureScript/CodeGen/C/Optimizer/Inliner.purs#L92-L104

https://github.com/pure-c/pure-c/blob/187fb7f54cbb890cfd276f72ab04186c067b92a9/runtime/purescript.h#L256

Essentially we have to dereference a pointer, allocate new heap memory, initialize it, and copy the now negated value over. A sizeof (purs_any_t) on my machine yields 24, whereas a pointer to one is only 8. I think we should stop heap allocating the boxes and just copy the structs around. It will also take pressure off the gc. At this point, however, it would have a large knock on effect into the existing libraries, so we should develop this on a branch and attempt to get it merged after we see #12 passing with the current approach, I'd say.

felixSchl commented 5 years ago

Closing this as not (realistically) actionable