什么GHC优化负责复制案例表达?

ben*_*ofs 7 optimization haskell ghc

给出以下代码:

{-# OPTIONS_GHC -funbox-strict-fields #-}
module Test where

data X = X !Int !Int

test (X a b) (X c d) = X (max a c) (max b d)
Run Code Online (Sandbox Code Playgroud)

GHC在使用优化进行编译时生成此核心(重命名以使读取更容易):

test
test =
  \ u v ->
    case u of x { X y z ->
    case v of c { X d e ->
    case tagToEnum# (<=# y d) of _ {
      False ->
        case tagToEnum# (<=# z e) of _ {
          False -> x;
          True -> X y e
        };
      True ->
        case tagToEnum# (<=# z e) of _ {
          False -> X d z;
          True -> c
        }
    }
    }
    }
Run Code Online (Sandbox Code Playgroud)

请注意GHC如何在总共4个不同的代码路径中生成.通常,代码路径的数量随着条件的数量呈指数增长.

什么GHC优化会导致这种行为?是否有控制此优化的标志?就我而言,这会产生巨大的代码膨胀,并且由于深层嵌套的case表达式而使核心转储很难读取.

ben*_*ofs 5

经过一些研究,我发现对此负责的优化是所谓的“case-of-case”转换,GHC 大概是在简化器中进行的,所以它不能被停用(因为它对于很多事情都是必要的GHC 确实如此,并且简化器是 GHC 优化管道的一个组成部分)。

以下链接解释了案例如何导致重复:http : //lambda.jstolarek.com/2013/01/taking-magic-out-of-ghc-or-tracing-compilation-by-transformation/

特别是,case-of-case 变成了这个:

case ( 
  case C of 
      B1 -> F1
      B2 -> F2
 ) of
    A1 -> E1
    A2 -> E2
Run Code Online (Sandbox Code Playgroud)

进入以下内容:

case C of    
    B1 -> case F1 of
              A1 -> E1
              A2 -> E2
    B2 -> case F2 of
              A1 -> E1
              A2 -> E2
Run Code Online (Sandbox Code Playgroud)

外壳已被复制并推入分支。