如何在 GHCI 中加载优化代码?

How can I load optimized code in GHCI?

我正在编写一个依赖于优化的模块。我想在 ghci 中测试这个模块。但是以 --interactive 模式启动 ghc 会自动禁用优化;如果我用 -O 编译模块然后尝试在交互式会话中加载它,ghc 坚持以解释模式加载它。

对于区分优化和未优化模块的简单测试用例,下面的 isOptimized 在启用优化的情况下评估为 True,但在关闭优化的情况下 False

isOptimized :: Bool
isOptimized = g

g :: Bool
g = False

{-# NOINLINE g #-}
{-# RULES "g/True"  g = True #-}

使用 ghci -fobject-code -O Test.hscabal repl --ghc-options="-fobject-code -O"。更详细:

  1. ghci 必须用 -fobject-code flag.

  2. 调用
  3. 必须在命令行上 -fobject-code 之后或在 OPTIONS_GHC 附注中给出优化标志模块的顶部。尝试 ghc --interactive -O -fobject-code 会产生一条警告,指出“-O 与 --interactive 冲突;-O 被忽略。”这可能是一个错误。

  4. 如果您正在处理一个 cabalized 项目并使用 cabal repl,您需要在命令行(即 cabal repl --ghc-options="-fobject-code -O")或 pragma 中传递标志.调用 ghci 时,Cabal(当前)丢弃在 .cabal 文件中设置的优化标志 ghc-options;事实上,它显式地设置了 -O0。这可能是一个错误。

无论如何请注意,在优化和未优化模式之间切换时,有时您需要手动强制重新编译。由于某些原因,只要 -fobject-code 保持打开状态,当优化标志更改时构建工件不会失效。如果从头开始,您在 .cabal 文件中设置了 -fobject-code,编译模块的 运行 cabal repl,然后记住您需要在命令行上设置 -O和 运行 cabal repl --ghc-options=-O,ghc 将愉快地加载先前编译的、未优化的模块。这也可能是一个错误。

测试单个模块最可靠的方案似乎是将{-# OPTIONS_GHC -fobject-code -O #-}放在模块的顶部。无论您如何调用 ghci,您都将获得优化的代码。我没有调查在多模块情况下会发生什么,其中一些但不是所有模块都有 pragma。

顺便说一句,请注意只有模块中的代码被优化了。即使启用了优化,在 repl 中计算 g 也总是会产生 False,因为 repl 输入不受重写规则的约束。