代码之家  ›  专栏  ›  技术社区  ›  bennofs

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

  •  7
  • bennofs  · 技术社区  · 8 年前

    给定以下代码:

    {-# 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)
    

    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
            }
        }
        }
        }
    

    注意GHC是如何产生总计 4. 不同的代码路径。通常,代码路径的数量随着条件的数量呈指数增长。

    什么GHC优化导致了这种行为?是否有控制此优化的标志?在我的例子中,这会产生巨大的代码膨胀,并且由于深度嵌套的case表达式,使得核心转储非常难以读取。

    1 回复  |  直到 8 年前
        1
  •  5
  •   bennofs    8 年前

    经过一些研究,我发现,负责这一点的优化就是所谓的“案例”转换,GHC可能在简化器中进行了这种转换,因此它不能被停用(因为GHC所做的很多事情都是必需的,而简化器是GHC优化管道的一个组成部分)。

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

    特别是,案例的情况如下:

    case ( 
      case C of 
          B1 -> F1
          B2 -> F2
     ) of
        A1 -> E1
        A2 -> E2
    

    分为以下几部分:

    case C of    
        B1 -> case F1 of
                  A1 -> E1
                  A2 -> E2
        B2 -> case F2 of
                  A1 -> E1
                  A2 -> E2
    

    其中外壳被复制并推入分支。