12

次のような Haskell コードがあります。

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

ZRepaライブラリから:.取得され、次のように定義されます。

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

式 right of$は配列インデックスを定義し、 whilefはそのインデックスを取得してペアを返す関数です。これは、次のコアにコンパイルされます。

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

4

1 に答える 1

12

実際、 の 2 つの分岐case ># x_s32E 0 ofは同一であるため、case冗長です。case両方のブランチが同一になった後、同一のブランチの削除は実行されないようです-おそらくバグレポートの価値があります。これは適切かもしれませんが、負の除数に対して生成されたコアは良好であるため、新しいバグを報告しました。

機械除算演算子に直接マップする、より単純な(正当に否定できないquot場合)を使用iすると、コードが単純になり、そのために分岐を生成する必要がなくなります。

于 2012-10-30T14:16:13.157 に答える