【问题标题】:foreign import prim call to LLVM对 LLVM 的外国进口 prim 调用
【发布时间】:2015-11-25 06:50:21
【问题描述】:

我正在尝试使用 post 中的想法调用用 LLVM 编写的外国导入 prim,但我只是不断收到段错误。这是我目前所拥有的。

在 Haskell 中

{-# LANGUAGE GHCForeignImportPrim #-}
{-# LANGUAGE MagicHash, UnboxedTuples #-}
{-# LANGUAGE ForeignFunctionInterface, UnliftedFFITypes #-}

import GHC.Prim

foreign import prim "primllvm" primllvm :: Word# -> Word# -> (# Word#, Word# #)

.ll 文件中

define cc10 void @primllvm(i64* %baseReg, i64* %sp, i64* %hp, i64* %buffer, i64 %length, i64 %r3, i64 %r4, i64 %r5, i64 %r6, i64* %spLim, float %f1, float %f2, float %f3, float %f4, double %d1, double %d2)
{
  %fp = bitcast i64* %sp to void(i64*, i64*, i64*, i64*, i64, i64, i64, i64, i64, i64*, float, float, float, float, double, double)*
  tail call cc10 void %fp(i64* %baseReg, i64* %sp, i64* %hp, i64* %buffer, i64 %length, 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
}

理论上我认为这应该只是将它的参数作为元组返回,但就像我说的那样,它只是段错误。任何帮助来完成这项工作表示赞赏。

【问题讨论】:

    标签: haskell llvm ghc ffi llvm-ir


    【解决方案1】:

    我发现你的代码有两个问题:

    1. 虽然你的签名说你在 Haskell 端传入了两个 Word# 参数,但在 LLC 端你有 i64* %bufferi64 %length(注意类型 %buffer 是指针类型!)。

    2. sp 中多了一层间接性:sp 指向栈,栈顶是延续指针。您的代码似乎试图将堆栈指针解释为函数指针本身。

    我不了解 LLVM,我只是通过查看您链接的博客文章、了解 GHC 和玩耍来拼凑起来的;所以我最终不得不求助于查看clang 的输出,所以可能有一种更有效的方法来处理#2,但无论如何这里有一个版本可以工作并实现两个 64 位数字的交换:

    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
    }
    

    用于测试的 Haskell 代码:

    {-# 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)
    

    建筑:

    llc -filetype=obj -o Define.o Define.ll
    ghc --make Use.hs Define.o
    

    【讨论】:

      猜你喜欢
      • 2017-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-01
      • 2016-03-18
      • 2023-03-29
      • 1970-01-01
      相关资源
      最近更新 更多