我遇到的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中,(外部)putchar被声明两次,但第二次使用名称putchar1。我很清楚为什么会这样,但对于一个很好的通用方法来说,这并不是很好的意义。即我不想把一切都放在一个巨大的CodeGenModule里面。
这让我想到了另一个相关的问题。 LLVM-Haskell绑定是否适合构建编译器的后端。也许有了上面的合理解决方案 - 我可以找到一种方法来使用它......但是手写红外代码似乎更简单......
答案 0 :(得分:3)
您在newNamedFunction "putchar"
monad中调用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