Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I load optimized code in GHCI?

I am writing a module that relies on optimization. I want to test this module in ghci. But starting ghc in --interactive mode automatically disables optimization; if I compile the module with -O and then try to load it in an interactive session, ghc insists on loading it in interpreted mode.

For a simple test case to distinguish optimized and unoptimized modules, isOptimized below evaluates to True with optimization on, but False with optimization off:

isOptimized :: Bool
isOptimized = g

g :: Bool
g = False

{-# NOINLINE g #-}
{-# RULES "g/True"  g = True #-}
like image 559
Christian Conkle Avatar asked Jan 10 '15 22:01

Christian Conkle


1 Answers

Either use ghci -fobject-code -O Test.hs or cabal repl --ghc-options="-fobject-code -O". In more detail:

  1. ghci must be invoked with the -fobject-code flag.

  2. Optimization flag(s) must be given after -fobject-code on the command line, or in an OPTIONS_GHC pragma at the top of the module. Trying ghc --interactive -O -fobject-code produces a warning that "-O conflicts with --interactive; -O ignored." This is perhaps a bug.

  3. If you're working on a cabalized project and using cabal repl, you need to pass the flags either on the command line (i.e. cabal repl --ghc-options="-fobject-code -O") or in a pragma. Cabal (currently) discards optimization flags set in the .cabal file with ghc-options when invoking ghci; in fact, it explicitly sets -O0 instead. This is perhaps a bug.

Note in any case that you sometimes need to force recompilation manually when switching between optimized and unoptimized mode. Build artifacts are, for some reason, not invalidated when the optimization flags change so long as -fobject-code remains on. If, starting from a clean slate, you have -fobject-code set in your .cabal file, run cabal repl which compiles the module, and then remember you need to set -O on the command line and run cabal repl --ghc-options=-O, ghc will happily load the previously-compiled, unoptimized module. This is also perhaps a bug.

The most reliable scenario for testing a single module seems to be to put {-# OPTIONS_GHC -fobject-code -O #-} at the top of the module. You will get optimized code no matter how you invoke ghci. I haven't investigated what happens in multi-module situations where some but not all modules have the pragma.

Incidentally, note that only code in the module is optimized. Even with optimization on, evaluating g in the repl will always produce False, because the repl input is not subject to rewrite rules.

like image 194
Christian Conkle Avatar answered Sep 20 '22 18:09

Christian Conkle