2013-04-24 63 views
5

我與LLVM-Haskell綁定的問題是我得到「重複」名稱。我認爲解釋我的問題的最好方法是用一個小的具體例子(注意這個例子是人爲設計的,對於這樣一個小例子,它有簡單的方法......但它確實指出了我的問題)。Haskell LLVM - 創建重複函數

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 

如果你現在運行這個程序哈斯克爾(你需要一些像進口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綁定是否適合構建編譯器的後端。也許有一個合理的解決方案上面 - 我可以找出一種方法來使用它...但似乎更簡單,只需手寫紅外代碼...

回答

3

你打電話給newNamedFunction "putchar"裏面的CodeGenModule monad兩次,這明顯具有將putchar兩次加到模塊的副作用。這導致兩個聲明而不是錯誤的事實可能是一個錯誤,請考慮報告它。要解決這個問題,只需將putc設置爲參數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 
+0

這是一個不錯的解決方案。 – 2013-04-24 22:46:29

+0

如果您要求庫聲明「putchar」函數兩次,則聲明兩次。這不是一個錯誤。這裏提出的解決方案是正確的。如果你有更多的功能需要維護,你可以使用getModuleValues獲取模塊的聲明功能。請參閱llvm:example/Vector.hs。但要小心這個錯誤:https://github.com/bos/llvm/issues/78 – Lemming 2016-08-02 08:10:59