Haskell LLVM - Созданы дублирующие функции
Проблема с привязками LLVM-Haskell заключается в том, что я получаю "дублированные" имена. Я думаю, что лучший способ объяснить мою проблему - это маленький конкретный пример (обратите внимание, что пример придуман, и для такого небольшого примера есть простые способы обойти его... однако он действительно указывает на мою проблему).
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
Если вы сейчас запустите эту программу на Haskell (вам понадобится несколько импортов, таких как Data.Int/Word и LLVM.Core), вы получите следующий вывод.
; 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
}
Проблема в том, что в IR (внешний) путчар объявляется дважды, но второй раз с именем путчар1. У меня есть хорошее представление о том, почему это так, но не очень хорошо для общего подхода. Т.е. я не хочу помещать все внутри одного гигантского CodeGenModule.
Это подводит меня к другой связанной проблеме. Подходит ли привязка LLVM-Haskell для построения серверной части компилятора. Возможно, с разумным решением вышеупомянутого - я могу найти способ использовать это... но кажется, что проще просто написать код ИК...
1 ответ
Ты звонишь newNamedFunction "putchar"
внутри CodeGenModule
монада дважды, что, очевидно, имеет побочный эффект от добавления putchar
в модуль дважды. Тот факт, что это приводит к двум объявлениям вместо ошибки, вероятно, является ошибкой, пожалуйста, рассмотрите возможность сообщения об этом. Чтобы это исправить, просто сделайте putc
параметр simple
а также easy
, Это будет выглядеть примерно так (не проверено):
simple :: Function (Int32 -> IO Word32) -> TFunction (Int32 -> IO Word32)
simple putc =
createNamedFunction ExternalLinkage "simple" $ \x -> do
call putc x
call putc x
ret (0 :: Word32)
easy :: Function (Int32 -> IO Word32) -> Function (Int32 -> IO Word32)
-> TFunction (Int32 -> IO Word32)
easy putc simple' =
createNamedFunction ExternalLinkage "easy" $ \x -> do
call simple' x
y <- add x (42 :: Int32)
call putc y
ret (0 :: Word32)
main :: IO ()
main = do
m <- newNamedModule "Main"
defineModule m $ do
putc <- newNamedFunction ExternalLinkage "putchar"
simple' <- simple putc
easy putc simple'
writeBitcodeToFile "SillyLib" m