簡體   English   中英

GHC生成冗余核心操作

[英]GHC Generating Redundant Core Operations

我有以下程序將6位ASCII轉換為二進制格式。

ascii2bin :: Char -> B.ByteString
ascii2bin = B.reverse . fst . B.unfoldrN 6 decomp . to6BitASCII -- replace to6BitASCII with ord if you want to compile this
    where decomp n = case quotRem n 2 of (q,r) -> Just (chr r,q)

bs2bin :: B.ByteString -> B.ByteString
bs2bin = B.concatMap ascii2bin

這產生了以下核心部分:

Rec {
$wa
$wa =
  \ ww ww1 ww2 w ->
    case ww2 of wild {
      __DEFAULT ->
        let {
          wild2
          wild2 = remInt# ww1 2 } in
        case leWord# (int2Word# wild2) (__word 1114111) of _ { 
          False -> (lvl2 wild2) `cast` ...;                                                                                   
          True ->
            case writeWord8OffAddr#
                   ww 0 (narrow8Word# (int2Word# (ord# (chr# wild2)))) w
            of s2 { __DEFAULT ->
            $wa (plusAddr# ww 1) (quotInt# ww1 2) (+# wild 1) s2
            }   
        };  
      6 -> (# w, (lvl, lvl1, Just (I# ww1)) #)
    }   
end Rec }

注意那個ord . chr == id ord . chr == id ,所以這里有一個冗余操作: narrow8Word# (int2Word# (ord# (chr# wild2)))

有沒有理由GHC不必要地從Int - > Char - > Int轉換,或者這是一個代碼生成不良的例子? 這可以優化嗎?

編輯:這是使用GHC 7.4.2,我沒有嘗試與任何其他版本編譯。 我已經發現問題仍然存在於GHC 7.6.2中,但是在github上的當前HEAD分支中刪除了冗余操作。

有沒有理由GHC不必要地從Int -> Char -> Int ,或者這是一個代碼生成不良的例子? 這可以優化嗎?

不是(對兩者而言)。 你從-ddump-simpl獲得的核心不是結束。 在通往匯編代碼的途中,仍然有一些優化和轉換。 但是在這里刪除冗余轉換實際上並不是一種優化。

它們可以在核心和組件之間移除。 關鍵在於這些原始 - 除了縮小 - 都是無操作,它們只存在於核心,因為它是鍵入的。 由於它們是無操作,因此核心中是否存在冗余鏈並不重要。

7.6.1從代碼生成的程序集[它比7.4.2產生的更可讀,所以我認為] - 用ord而不是to6BitASCII - 是

ASCII.$wa_info:
_cXT:
    addq $64,%r12
    cmpq 144(%r13),%r12
    ja _cXX
    movq %rdi,%rcx
    cmpq $6,%rdi
    jne _cXZ
    movq $GHC.Types.I#_con_info,-56(%r12)
    movq %rsi,-48(%r12)
    movq $Data.Maybe.Just_con_info,-40(%r12)
    leaq -55(%r12),%rax
    movq %rax,-32(%r12)
    movq $(,,)_con_info,-24(%r12)
    movq $lvl1_rVq_closure+1,-16(%r12)
    movq $lvl_rVp_closure+1,-8(%r12)
    leaq -38(%r12),%rax
    movq %rax,0(%r12)
    leaq -23(%r12),%rbx
    jmp *0(%rbp)
_cXX:
    movq $64,192(%r13)
_cXV:
    movl $ASCII.$wa_closure,%ebx
    jmp *-8(%r13)
_cXZ:
    movl $2,%ebx
    movq %rsi,%rax
    cqto
    idivq %rbx
    movq %rax,%rsi
    cmpq $1114111,%rdx
    jbe _cY2
    movq %rdx,%r14
    addq $-64,%r12
    jmp GHC.Char.chr2_info
_cY2:
    movb %dl,(%r14)
    incq %r14
    leaq 1(%rcx),%rdi
    addq $-64,%r12
    jmp ASCII.$wa_info
    .size ASCII.$wa_info, .-ASCII.$wa_info

narrow8Word# (int2Word# (ord# (chr# wild2)))出現在核心中的部分位於cmpq $1114111, %rdx 如果商不超出范圍,則代碼跳轉到_cY2 ,不再包含此類轉換。 一個字節寫入數組,一些指針/計數器遞增,就是這樣,跳回到頂部。

我認為有可能從GHC產生更好的代碼,但冗余的無操作轉換已經消失。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM