Problem, który mam z powiązaniami LLVM-Haskell, polega na tym, że otrzymuję "zduplikowane" nazwy. Myślę, że najlepszym sposobem na wyjaśnienie mojego problemu jest mały konkretny przykład (zauważ, że przykład jest wymyślny, a na tak mały przykład są proste sposoby na jego obejście ... jednak wskazuje to na mój problem).Haskell LLVM - Powielone funkcje utworzone
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
Jeśli teraz uruchomić ten program Haskell (będziesz potrzebować import jak Data.Int/Word i LLVM.Core), można uzyskać następujące dane wyjściowe.
; 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
}
Problem polega na tym, że w IR, (zewnętrzna) putchar jest zadeklarowana dwukrotnie, ale po raz drugi z nazwą putchar1. Mam dobre wyczucie tego, dlaczego tak jest, ale nie ma to sensu dla dobrego, ogólnego sposobu obejścia tego. To znaczy. Nie chcę wrzucać wszystkiego do jednego gigantycznego CodeGenModule.
To doprowadza mnie do kolejnego pokrewnego problemu. Czy powiązanie LLVM-Haskell jest odpowiednie do budowania zaplecza kompilatora. Być może rozsądnym rozwiązaniem powyższego - mogę znaleźć sposób na jego użycie ... ale wydaje się prostsze po prostu ręczne napisanie kodu IR ...
To dobre rozwiązanie. –
Jeśli poprosisz bibliotekę o dwukrotne zadeklarowanie funkcji "putchar", zostanie ona zadeklarowana dwukrotnie. To nie jest błąd. Proponowane tutaj rozwiązanie jest właściwe. Jeśli masz więcej funkcji do utrzymania, możesz użyć getModuleValues, aby uzyskać deklarowane funkcje modułu. Zobacz llvm: example/Vector.hs. Ale uważaj na ten błąd: https://github.com/bos/llvm/issues/78 – Lemming