Il problema che sto avendo con i binding LLVM-Haskell è che ottengo nomi "duplicati". Penso che il modo migliore per spiegare il mio problema sia con un piccolo esempio concreto (si noti che l'esempio è artificioso, e per un piccolo esempio ci sono modi semplici per aggirarlo ... comunque sottolinea il mio problema).Haskell LLVM - Funzioni duplicate create
putc :: TFunction (Int32 -> IO Word32)
putc = newNamedFunction ExternalLinkage "putchar"
simple :: TFunction (Int32 -> IO Word32)
simple = do
internalputc <- putc
createNamedFunction ExternalLinkage "simple" $ \x -> do
call internalputc x
call internalputc x
ret (0 :: Word32)
easy :: TFunction (Int32 -> IO Word32)
easy = do
internalputc <- putc
internalsimple <- simple
createNamedFunction ExternalLinkage "easy" $ \x -> do
call internalsimple x
y <- add x (42 :: Int32)
call internalputc y
ret (0 :: Word32)
main :: IO()
main = do
m <- newNamedModule "Main"
defineModule m easy
writeBitcodeToFile "SillyLib" m
Se ora si esegue questo programma Haskell (avrete bisogno di alcune importazioni come Data.Int/Word, e LLVM.Core), si otterrà il seguente risultato.
; ModuleID = 'SillyLib'
declare i32 @putchar(i32)
declare i32 @putchar1(i32)
define i32 @simple(i32) {
_L1:
%1 = call i32 @putchar1(i32 %0)
%2 = call i32 @putchar1(i32 %0)
ret i32 0
}
define i32 @easy(i32) {
_L1:
%1 = call i32 @simple(i32 %0)
%2 = add i32 %0, 42
%3 = call i32 @putchar(i32 %2)
ret i32 0
}
Il problema è che in IR, la (esterno) putchar è dichiarato due volte, ma la seconda volta con il nome putchar1. Ho un buon senso sul perché questo sia, ma non è un buon senso per un buon modo generale. Cioè Non voglio dover mettere tutto all'interno di un gigantesco CodeGenModule.
Questo mi porta ad un altro problema correlato. Il binding LLVM-Haskell è appropriato per la creazione del back-end di un compilatore. Forse con una soluzione ragionevole a quanto sopra - posso capire un modo per usarlo ... ma sembra più semplice scrivere a mano il codice IR ...
Questa è una bella soluzione. –
Se si chiede alla libreria di dichiarare la funzione "putchar" due volte, viene dichiarata due volte. Questo non è un bug. La soluzione suggerita qui è giusta. Se si dispone di più funzioni da mantenere, è possibile utilizzare getModuleValues per ottenere le funzioni dichiarate di un modulo. Vedi llvm: example/Vector.hs. Ma fai attenzione a questo bug: https://github.com/bos/llvm/issues/78 – Lemming