Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using GHC API to compile a program with optimisation

I want to compile a Haskell module to GHC Core, with optimisations applied, and use the resulting core output. However, when I use compileToCoreSimplified it doesn't seem to run all the normal optimisations. Taking the program:

{-# OPTIONS_GHC -O2 #-}
module LensOpt(pick) where
import Control.Lens
data Record = Record {_field :: String}
field = lens _field $ \r x -> r{_field=x}
pick = Record "test" ^. field

When run through ghc -ddump-simple I get the optimal output:

LensOpt.pick1 :: GHC.Prim.Addr#
LensOpt.pick1 = "test"#

pick :: String
pick = GHC.CString.unpackCString# LensOpt.pick1

However, when compiled using compileToCoreSimplified I get the output:

s1 :: Addr#
s1 = "test"#

s2 :: [Char]
s2 = unpackCString# s1

s3 :: Record
s3 = Record s2

pick :: String
pick = case s3 of { Record ds -> ds }

I am invoking compileToCoreSimplified with:

import GHC
import GhcPlugins
import GHC.Paths

main = runGhc (Just libdir) $ do
    setTargets []
    dflags <- getSessionDynFlags
    setSessionDynFlags dflags{hscTarget = HscNothing}
    res <- compileToCoreSimplified "LensOpt.hs"
    liftIO $ writeFile "lens_api.txt" $ showSDoc dflags $ ppr res

How do I drive the GHC API to apply the full optimisations?

like image 544
Neil Mitchell Avatar asked Jun 20 '18 20:06

Neil Mitchell


1 Answers

You need to turn on the optimizations you want to run in the DynFlags.

You can do that either by specifying an optimization level (0..2) and setting optimizations based on that (updOptLevel), or by turning on individual optimizations such as Opt_Specialise:

main = runGhc (Just libdir) $ do
    setTargets []
    dflags <- getSessionDynFlags
    setSessionDynFlags $ updOptLevel 2 $ dflags{hscTarget = HscNothing}
like image 125
Cactus Avatar answered Dec 04 '22 14:12

Cactus