从Haskell的Core中删除带有重复分支的“case”

时间:2012-10-30 13:18:19

标签: haskell core repa

我有一段看起来像这样的Haskell代码:

fst . f $ (Z :. i `div` 2)

Z:.取自Repa库,定义如下:

data Z = Z deriving (Show, Read, Eq, Ord)
infixl 3 :. 
data tail :. head = !tail :. !head deriving (Show, Read, Eq, Ord)

$的表达式右边定义了一个数组索引,而f是一个获取该索引并返回一对的函数。这将编译为以下核心:

case f_a2pC
       (case ># x_s32E 0 of _ {
          False ->
            case <# x_s32E 0 of _ {
              False -> :. Z (I# (quotInt# x_s32E 2));
              True -> :. Z (I# (-# (quotInt# (+# x_s32E 1) 2) 1))
            };
          True ->
            case <# x_s32E 0 of _ {
              False -> :. Z (I# (quotInt# x_s32E 2));
              True -> :. Z (I# (-# (quotInt# (+# x_s32E 1) 2) 1))
            }
        })
of _ { (x1_a2Cv, _) ->
x1_a2Cv
}

对我而言,似乎很明显(可能不正确)中间案例陈述(># x_s32E 0作为审查员的陈述)是多余的,因为两个分支都是相同的。我有什么办法可以摆脱它吗?我使用在Repa文档中建议的GHC选项编译我的代码:-O2 -Odph -fno-liberate-case -funfolding-use-threshold1000 -funfolding-keeness-factor1000

1 个答案:

答案 0 :(得分:12)

实际上case ># x_s32E 0 of的两个分支是相同的,因此case是多余的。似乎case - 消除了相同的分支在两个分支变得相同之后不会运行 - 可能值得一个错误报告。 This one可能是相关的,但由于为负除数生成的核心是好的,我提交了new bug

使用更简单的quot - 如果i不能合法地否定 - 直接映射到机器分区运算符会使代码更简单,因此不需要为此生成分支。