Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Haskell compiler

Haskell compiler

Haskell compiler
Institute of Computer Science, University of Wrocław
Seminar: Implementing compilers of functional languages
28.01.2016

Rafał Łasocha

January 28, 2016
Tweet

More Decks by Rafał Łasocha

Other Decks in Programming

Transcript

  1. Spineless Tagless G-Machine
    Haskell compiler
    Rafal Lasocha
    Wroclaw, 28th January 2016
    Rafal Lasocha Haskell compiler

    View full-size slide

  2. Spineless Tagless G-Machine
    Phases of compilation
    Spineless Tagless G-Machine
    Rafal Lasocha Haskell compiler

    View full-size slide

  3. Spineless Tagless G-Machine
    Rafal Lasocha Haskell compiler

    View full-size slide

  4. Spineless Tagless G-Machine
    Rafal Lasocha Haskell compiler

    View full-size slide

  5. Spineless Tagless G-Machine
    Rewriting rules
    {−# RULES
    ”map/map” forall f g xs. map f (map g xs) = map (f.g) xs
    ”map/append” forall f xs ys. map f (xs ++ ys) = map f xs ++ map f ys
    #−}
    Rafal Lasocha Haskell compiler

    View full-size slide

  6. Spineless Tagless G-Machine Operational semantics
    map f [] = []
    map f (y:ys) = (f y) : (map f ys)
    map = {} \n {f,xs} ->
    case xs of
    Nil {} -> Nil {}
    Cons {y,ys} -> let fy = {f,y} \u {} -> f {y}
    mfy = {f,ys} \u {} -> map {f,ys}
    in Cons {fy,mfy}
    Lambda form: free vars X args -> expression
    Rafal Lasocha Haskell compiler

    View full-size slide

  7. Spineless Tagless G-Machine Operational semantics
    constructors are always saturated
    no types
    on the RHS of let(rec) there are only lambda forms
    only thing which may force us to evaluate, is case expression
    Rafal Lasocha Haskell compiler

    View full-size slide

  8. Spineless Tagless G-Machine Operational semantics
    Updateable flag: boolean, either ”u” (updatable) or ”n” (not updatable)
    Our language is lazy, so after evaluation of suspended computation, we
    should update something, to not evaluate the same code again
    but maybe already during compilation we can deduce, that we won’t have
    to update some closures?
    functions with non-empty argument list - they don’t need updating
    partial applications - the same ( vs \n {} -> f {x1, ..., xm} )
    saturated constructor - the same
    thunks - these are rather updatable
    Rafal Lasocha Haskell compiler

    View full-size slide

  9. Spineless Tagless G-Machine Operational semantics
    few stacks: argument stack, return stack, update stack, heap, global
    environment
    value, on the argument stack are either heap addresses or primitive
    integers
    4 possible states of compiler
    Eval e p - evaluate expression e in environemnt p
    Enter a - apply the closure at address a to the arguments on the
    argument stack
    ReturnCon c ws - Return the constructor c applied to values ws to the
    continuation on the return stack
    ReturnInt k - Return the primitive integer k to the continuation on the
    return stack
    Rafal Lasocha Haskell compiler

    View full-size slide

  10. Spineless Tagless G-Machine Operational semantics
    Initial state
    Rafal Lasocha Haskell compiler

    View full-size slide

  11. Spineless Tagless G-Machine Operational semantics
    Function application
    Eval e p - evaluate expression e in environment p
    Rafal Lasocha Haskell compiler

    View full-size slide

  12. Spineless Tagless G-Machine Operational semantics
    Enter non-updatable closure
    Enter a - apply the closure at address a to the arguments on the
    argument stack
    Rafal Lasocha Haskell compiler

    View full-size slide

  13. Spineless Tagless G-Machine Operational semantics
    Evaluate case statement
    ReturnCon c ws - Return the constructor c applied to values ws to the
    continuation on the return stack
    Rafal Lasocha Haskell compiler

    View full-size slide

  14. Spineless Tagless G-Machine Operational semantics
    Applying updatable closures
    assuming a is an address of the updatable closure we try to Enter (Enter
    a)
    clean argument and return stacks, and save triple (”update frame”)
    (as, rs, a) to the update frames stack
    now just evaluate and wait until our program ”crash” because lack of
    values in either return stack or argument stack
    Rafal Lasocha Haskell compiler

    View full-size slide

  15. Spineless Tagless G-Machine Operational semantics
    Applying updatable closures
    Rafal Lasocha Haskell compiler

    View full-size slide

  16. Spineless Tagless G-Machine Operational semantics
    Generating code
    target language will be C
    it’s not perfect, it’s not very efficient, but it works
    mapping haskell functions to C functions doesn’t work
    each closure becomes C function, but without arguments
    stacks will be managed by us
    but subsequently entering functions will cause our stack to grow...
    while (TRUE) { cont = (*cont)(); }
    Rafal Lasocha Haskell compiler

    View full-size slide

  17. Spineless Tagless G-Machine Operational semantics
    Closure representation in memory
    Rafal Lasocha Haskell compiler

    View full-size slide

  18. Spineless Tagless G-Machine Operational semantics
    Garbage collection
    two space GC
    evacuating code handles moving specific closure from 1st space to 2nd
    it also overrides in 1st space with forwarding pointer
    ... and returns new closure address to the caller
    scavenging code knows how to iterate evacuating code on each pointer in
    closure
    it also replace old pointers with new ones
    forwarding pointers - simple return of associated pointer
    Rafal Lasocha Haskell compiler

    View full-size slide

  19. Spineless Tagless G-Machine Operational semantics
    Something about translating to C
    STG has two stack pointers - one for integers, and one for pointers.
    # apply3 = {} \n {f,x} -> f {x,x,x}
    Node = SpA[0]
    t = SpA[1]
    SpA[0] = t
    SpA[-1] = t
    SpA = SpA - 1
    ENTER( Node ) # Node is a closure, not code ptr
    Rafal Lasocha Haskell compiler

    View full-size slide