2012-10-30 13 views
12

Ho un pezzo di codice Haskell che assomiglia a questo:Rimozione "caso" con rami duplicati dal Centro della Haskell

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

Z e :. sono tratte da Repa biblioteca e sono definiti in questo modo:

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

L'espressione destra di $ definisce un indice di matrice, mentre f è una funzione che prende quell'indice e restituisce una coppia. Questo compila in seguito Nucleo:

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 
} 

A me sembra ovvio (forse erroneamente) che il caso affermazione centrale (quello con ># x_s32E 0 come scrutinee) è ridondante, in quanto entrambi i rami sono identici. C'è qualcosa che posso fare per liberarmene? Compilo il mio codice utilizzando le opzioni GHC consigliato nella documentazione Repa: -O2 -Odph -fno-liberare-caso -funfolding-uso-threshold1000 -funfolding-keeness-factor1000

+5

A meno che 'i' possa essere legittimamente negativo, si dovrebbe usare' quot' invece di 'div'. Questo dovrebbe risolverlo. –

+1

Hai ragione - questo risolve il mio problema. Puoi postare quel commento come risposta in modo che io possa accettarlo? –

risposta

12

Infatti i due rami del case ># x_s32E 0 of sono identici, e quindi che case è ridondante. Sembra che la separazione di case per i rami identici non venga eseguita dopo che entrambi i rami sono diventati identici, probabilmente vale un bug report. This one potrebbe essere pertinente, ma poiché il core generato per i divisori negativi è buono, ho archiviato uno new bug.

Utilizzo del più semplice quot - se i non può legittimamente negare - che esegue il mapping diretto all'operatore di divisione macchina rende il codice più semplice, in modo che non sia necessario generare rami per tale scopo.

+0

Grazie! Non sono sicuro che si tratti di un bug in GHC o del mio uso errato delle opzioni del compilatore. Proverò a ridurre questo problema a un esempio di lavoro minimo e, se persiste, riempirò un bug. –

+0

Ho fatto un po 'di riduzione e ho aperto un nuovo ticket. –