-
Notifications
You must be signed in to change notification settings - Fork 34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
adding support for generating code that uses ghc calling convention #50
Comments
There is already support for arbitrary calling conventions, see |
@NathanHowell that gives part of the story, but I think theres a teeny bit more work necessary to make it essentially as fast as a pure ghc call (in the ghc calling convention case). heres a way to hack it out without being dependent on RTS details: we'd at least need to write a K+1 arity function for each K arity we want to support, but we could probably make do with just doing that many, ish (depending on some fiddly details of register types etc), and have a type classe wrapper for the lifted variants of this that does the right black magic. (ie we just need the ghc cmm prim to have the right arity and number of word/pointer like args, since the cmm shim won't actually touch any pointer / word like args but the last one!). This seems like it'd be the simplest way to shim in FAST native calls using the ghc convention. |
phrased differently: for the lifted word/pointer/float args, we count the number of word/pointer args, choose the cmm primop with that count, unsafe coerce that dude to the right type, and apply it to the unlifted set of args. theres probably a few fiddly details i'm overlooking, but thats the main parts. also would play safely with some other bits I'm forgetting probably. I'll need to test out this idea, but assuming that we can make sure ghc fully applies stuff right (which might take a smidge of template haskell, but the primops are fine). Alternatively, we could write 1 primop who's first arg is the fun pointer, and have the llvm side code all just have a dummy first arg that gets ignored. Then for each lifted/unlifted instance we want, just have some template haskell code that handles that |
we could probably do either approach pretty safely using the semantics laid out here on the ghc trac wiki http://hackage.haskell.org/trac/ghc/wiki/Commentary/Rts/HaskellExecution/FunctionCalls theres some subtlety to making sure it does the fast calling convention of how to view the args I think, and i'm totally punting on how to view the handling return values part of the story too. maybe the best way / or at least a way that might work more robustly if other approaches don't work, is to have something like (\ args1 ... argsn argsFunptr -> do cmmShm ) Unliftedval1 .... unlifitedvaln funpointer or maybe i'm missing the whole point. |
it looks like it'd be quite possible to generate code that respects the ghc calling convention, and perhaps provide a safe wrapper around running the code. (while also evading the c ffi overheads!). Which would also make it easier to generate fast calling convention code for ghc at runtime! (something that matters for me)
It might require writing a CMM (c minus minus ) shim or something, but I'm happy to look into it. And it looks like it'd be relatively sane to do for 7.6, and downright easy once ghc 7.8 stabilizes.
If i can sort it out and have it sanely working, would this be something that the maintainers would be open to merging in / helping maintain? (i think the code complexity for doing so won't be that high, and only 1-2 unsafe coerces may be needed internally :) )
any feedback / thoughts would be appreciated.
The text was updated successfully, but these errors were encountered: