5

The problem I am having with the LLVM-Haskell bindings is that I am getting "duplicated" names. I think the best way to explain my problem is with a small concrete example (note the example is contrived, and for such a small example there are easy ways around it... however it does point out my problem).

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

If you now run this haskell program (you'll need some imports like Data.Int/Word, and LLVM.Core), you'll get the following output.

; 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
}

The problem is that in the IR, the (external) putchar is declared twice, but the second time with the name putchar1. I have a good sense as to why this is, but not a good sense for a nice general way around this. I.e. I don't want to have to put everything inside of one giant CodeGenModule.

This brings me to the another related issue. Is the LLVM-Haskell binding appropriate for building the backend of a compiler. Perhaps with a reasonable solution to the above -- I can figure out a way to use it ... but it seems simpler just to hand write the IR code...

4

1 回答 1

3

您在monadnewNamedFunction "putchar"内部调用了两次,这显然具有两次添加到模块CodeGenModule的副作用。putchar这导致两个声明而不是错误的事实可能是一个错误,请考虑报告它。要解决此问题,只需为andputc设置一个参数。这看起来大致如下(未经测试):simpleeasy

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
于 2013-04-24T05:54:54.180 回答