我在使用LLVM-Haskell绑定时遇到了“重复”名称的问题。我认为最好的方法是用一个小的具体例子来解释我的问题(请注意,这个例子是人为的,对于这样一个小的例子有简单的解决方法...然而,它确实指出了我的问题)。
如果您现在运行这个Haskell程序(你需要一些导入,如Data.Int/Word和LLVM.Core),您将得到以下输出。
问题在于在IR中,(外部) putchar 声明了两次,但第二次使用了 putchar1 的名称。我知道这是为什么,但没有一个好的通用解决方法。也就是说,我不想把所有东西都放在一个巨大的 CodeGenModule 中。
这带我到另一个相关问题。LLVM-Haskell 绑定是否适合构建编译器的后端?也许有了上述问题的合理解决方案,我可以想出一种使用它的方法...但手写 IR 代码似乎更简单。
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中,(外部) putchar 声明了两次,但第二次使用了 putchar1 的名称。我知道这是为什么,但没有一个好的通用解决方法。也就是说,我不想把所有东西都放在一个巨大的 CodeGenModule 中。
这带我到另一个相关问题。LLVM-Haskell 绑定是否适合构建编译器的后端?也许有了上述问题的合理解决方案,我可以想出一种使用它的方法...但手写 IR 代码似乎更简单。