国外进口对LLVM的调用

时间:2015-11-25 06:50:22

标签: haskell llvm ghc ffi llvm-ir

我试图使用来自post的想法来调用LLVM中编写的外来导入文章,但我只是继续得到段错误。这就是我目前所拥有的。

在Haskell

var priorities = "High:1,Medium:2,Low:3,Low:4,Medium:5,High:6,Medium:7,"
                 + "High:8,Low:9,Low:10,Medium:11,High:12,Low:13,Medium:14,"
                 + "High:15,High:16,Low:17,Medium:18,Low:19,High:20";

var keys = ["High", "Medium", "Low"], res = [];
keys.forEach(function(val) {
  res = res.concat(priorities.match(new RegExp(val + "\.\\w+(?=.*,)", "g")))
});
document.body.innerHTML = JSON.stringify(res)

并在{-# LANGUAGE GHCForeignImportPrim #-} {-# LANGUAGE MagicHash, UnboxedTuples #-} {-# LANGUAGE ForeignFunctionInterface, UnliftedFFITypes #-} import GHC.Prim foreign import prim "primllvm" primllvm :: Word# -> Word# -> (# Word#, Word# #) 文件中

.ll

理论上我认为这应该只是将它作为一个元组返回,但就像我说的那样,它只是段错误。任何帮助使这项工作受到赞赏。

1 个答案:

答案 0 :(得分:2)

我发现您的代码存在两个问题:

  1. 虽然您的签名表示您在Haskell方面传递了两个Word#参数,但在LLC方面,您有i64* %bufferi64 %length(注意类型{{1}是指针类型!)。

  2. 堆栈中的%buffersp点还有一个间接级别,堆栈顶部的东西是连续指针。您的代码似乎试图将堆栈指针解释为函数指针本身。

  3. 我不知道LLVM,我只是通过查看你链接的博客文章,知道GHC,玩游戏,将它拼凑在一起;所以我最终不得不求助于查看sp的输出,因此可能有一种更有效的方式来处理#2,但无论如何这里是一个可以工作并实现两个64位交换的版本数:

    clang

    用于测试的Haskell代码:

    define cc10 void @primllvm(i64* %baseReg, i64* %sp, i64* %hp,
                               i64 %x, i64 %y, i64 %r3, i64 %r4, i64 %r5, i64 %r6,
                               i64* %spLim,
                               float %f1, float %f2, float %f3, float %f4,
                               double %d1, double %d2)
    {
      %1 = getelementptr inbounds i64* %sp, i64 0
      %2 = load i64* %1, align 8
      %cont = inttoptr i64 %2 to void (i64*, i64*, i64*,
                                       i64, i64, i64, i64, i64, i64,
                                       i64*,
                                       float, float, float, float,
                                       double, double)*
    
      tail call cc10 void %cont(i64* %baseReg, i64* %sp, i64* %hp,
                                i64 %y, i64 %x, i64 %r3, i64 %r4, i64 %r5, i64 %r6,
                                i64* %spLim,
                                float %f1, float %f2, float %f3, float %f4,
                                double %d1, double %d2) noreturn
      ret void
    }
    

    大厦:

    {-# LANGUAGE GHCForeignImportPrim #-}
    {-# LANGUAGE MagicHash, UnboxedTuples, BangPatterns  #-}
    {-# LANGUAGE ForeignFunctionInterface, UnliftedFFITypes #-}
    
    import GHC.Prim
    import GHC.Word
    
    foreign import prim "primllvm" primllvm :: Word# -> Word# -> (# Word#, Word# #)
    
    main :: IO ()
    main = do
      let !(W# w1) = 12
          !(W# w2) = 34
          !(# w1', w2' #) = primllvm w1 w2
          x = W# w1'
          y = W# w2'
      print (x, y)