2013-04-24 5 views
5

내가 LLVM-Haskell 바인딩과 관련하여 겪고있는 문제는 "중복 된"이름을 얻는다는 것이다. 내 문제를 설명하는 가장 좋은 방법은 구체적인 예를 든다는 것입니다. (예제는 고안된 것이고, 작은 예를 들어 주위에 쉬운 방법이 있습니다 ... 그러나 내 문제를 지적합니다). 지금이 하스켈 프로그램을 실행하면Haskell LLVM - Duplicate Functions created

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 바인딩은 컴파일러의 백엔드 빌드에 적합합니까? 아마 위의 합리적인 해결책으로 - 나는 그것을 사용하는 방법을 알아낼 수 있습니다 ...하지만 그것은 단지 IR 코드를 작성하는 것이 더 간단 해 보입니다 ...

답변

3

CodeGenModule 모나드 안에 두 번 전화하면됩니다. 이것은 분명히 putchar을 모듈에 두 번 추가하는 부작용이 있습니다. 이 결과로 인해 오류가 아닌 두 번의 선언이 발생하는 경우 버그 일 가능성이 있으므로보고 해주십시오. 이 문제를 해결하려면 의 매개 변수를 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

좋은 해결책입니다. –

+0

"putchar"함수를 두 번 선언하도록 라이브러리에 요청하면 두 번 선언됩니다. 이것은 버그가 아닙니다. 여기에 제시된 해결책은 올바른 방법입니다. 유지 보수 할 함수가 더 많은 경우 getModuleValues를 사용하여 모듈의 선언 된 함수를 가져올 수 있습니다. llvm : example/Vector.hs를 참조하십시오. 그러나이 버그에주의하십시오 : https://github.com/bos/llvm/issues/78 – Lemming