bug in ghc specialiser?

Malcolm Wallace Malcolm.Wallace at cs.york.ac.uk
Wed Feb 11 11:58:14 EST 2009


Here is an apparent bug in ghc's specialisation rules.  The rewrite rule
generated by a SPECIALISE pragma seems to want to pattern-match on exact
dictionaries (as well as types).  But the compiler is not necessarily
able to fully resolve dictionaries before the rules are supposed to
fire.

First, the source code we want to specialise:

    {-# SPECIALISE
        hedgehog :: Float -> Vector3 Float
                          -> [Cell_8 (Coord3 Float)]
                          -> [Cell_8 (Vector3 Float)]
                          -> [(Coord3 Float, Coord3 Float)]
      #-}
    hedgehog  :: ( Fractional a, Cell cell vert, Eq vert
                 , Geom coord, Geom vector, Embed vector coord ) =>
                 a -> vector a
                   -> [cell (coord a)]
                   -> [cell (vector a)]
                   -> [(coord a, coord a)]

And the core + interface generated for this module contains the rule:

    "SPEC Hedgehog.hedgehog" ALWAYS forall
      Hedgehog.hedgehog @ GHC.Float.Float
                        @ RectGrid.Cell_8
                        @ CellTypes.MyVertex
                        @ Geometries.Coord3
                        @ Graphics.Rendering.OpenGL.GL.CoordTrans.Vector3
                        GHC.Float.$f16
                        RectGrid.$f2
                        CellTypes.$f1
                        Geometries.$f5
                        Geometries.$f3
                        Geometries.$f1
      = Hedgehog.hedgehog1

But in a different module, here is what the usage site looks like just
before the specialisation rules are supposed to fire:

    hedgehog_a4wy =
      Hedgehog.hedgehog
        @ GHC.Float.Float
        @ RectGrid.Cell_8
        @ CellTypes.MyVertex
        @ Geometries.Coord3
        @ Graphics.Rendering.OpenGL.GL.CoordTrans.Vector3
        $dFractional_a4xP
        RectGrid.$f2
        CellTypes.$f1
        (Dataset.$p2Embed
           @ Graphics.Rendering.OpenGL.GL.CoordTrans.Vector3
           @ Geometries.Coord3
           Geometries.$f1)
        (Dataset.$p1Embed
           @ Graphics.Rendering.OpenGL.GL.CoordTrans.Vector3
           @ Geometries.Coord3
           Geometries.$f1)
        Geometries.$f1

Notice how there are several dictionary selector functions sitting
there, so although some of the dictionaries match, not all do, and the
rule does not fire.  However, later the worker-wrapper transformation
is able to resolve those outstanding dictionaries, giving:

    hedgehog_a4wy =
      Hedgehog.$whedgehog
        @ GHC.Float.Float
        @ RectGrid.Cell_8
        @ CellTypes.MyVertex
        @ Geometries.Coord3
        @ Graphics.Rendering.OpenGL.GL.CoordTrans.Vector3
        GHC.Float.$f16
        RectGrid.$f2
        Geometries.$f5
        Geometries.$f3
        Geometries.$f1

So I'm left calling the worker for the polymorphic version of the
function, rather than the specialised monomorphic code I wanted.  Given
how many dictionaries are involved, and that this is the inner loop of
the program, I'm hoping there is a big performance win waiting for me,
if only I can get that specialised code to run!

Regards,
    Malcolm


More information about the Glasgow-haskell-users mailing list