Better calling conventions for strict functions (bang patterns)?
rrnewton at gmail.com
Fri Oct 23 13:53:44 UTC 2015
With module-level Strict and StrictData pragmas coming soon, one obvious
question is what kind of the code quality GHC can achieve for strict
When it came up in discussion in our research group we realized we didn't
actually know whether the bang patterns, `f !x`, on function arguments were
enforced by caller or callee.
Here's a Gist that shows the compilation of a trivial function:
foo :: Maybe Int -> Intfoo !x = case x of Just y -> y
If that function is compiled to *assume* its input is in WHNF, it should be
just as efficient as the isomorphic MLton/OCaml code, right? It only needs
to branch on the tag, do a field dereference, and return.
But as you can see from the STG and CMM generated, foo *does indeed* enter
the thunk, adding an extra indirect jump. Here's the body:
c3aY: if ((Sp + -8) < SpLim) goto c3aZ; else goto c3b0; c3aZ: // nop R1 =
PicBaseReg + foo_closure; call (I64[BaseReg - 8])(R2, R1) args: 8, res: 0,
upd: 8; c3b0: I64[Sp - 8] = PicBaseReg + block_c3aO_info; R1 = R2; Sp = Sp
- 8; if (R1 & 7 != 0) goto c3aO; else goto c3aP; c3aP: call (I64[R1])(R1)
returns to c3aO, args: 8, res: 8, upd: 8; c3aO: if (R1 & 7 >= 2) goto c3aW;
else goto c3aX; c3aW: R1 = P64[R1 + 6] & (-8); Sp = Sp + 8; call
(I64[R1])(R1) args: 8, res: 0, upd: 8; c3aX: R1 = PicBaseReg +
lvl_r39S_closure; Sp = Sp + 8; call (I64[R1])(R1) args: 8, res: 0, upd: 8;
The call inside c3aP is entering "x" as a thunk, which also incurs all of
the stack limit check code. I believe that IF the input could be assumed
to be in WHNF, everything above the label "c3aO" could be omitted.
So... if GHC is going to be a fabulous pure *and* imperative language, and
a fabulous lazy *and* strict compiler/runtime.. is there some work we can
do here to improve this situation? Would the following make sense:
- Put together a benchmark suite of all-strict programs with
Strict/StrictData (compare a few benchmark's generated code to MLton, if
- Modify GHC to change calling conventions for bang patterns -- caller
enforces WHNF rather than callee. Existing strictness/demand/cardinality
analysis would stay the same.
Unless there's something I'm really missing here, the result should be that
you can have a whole chain of strict function calls, each of which knows
its arguments and the arguments it passes to its callees are all in WHNF,
without ever generating thunk-entry sequences.
Thanks for your time,
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the ghc-devs