haskell - GHC 中如何实现整数比较?

标签 haskell ghc

起初,我想研究一下 Integer派生自类 Ord我在 GHC.Classes 中得到了这个定义

instance Ord Integer where
    (<=) = leInteger
    (>)  = gtInteger
    (<)  = ltInteger
    (>=) = geInteger
    compare = compareInteger
compareInteger指向另一个源文件,GHC.Integer.Type .它是这样定义的:
compareInteger :: Integer -> Integer -> Ordering
compareInteger (Jn# x)  (Jn# y) = compareBigNat y x
compareInteger (S#  x)  (S#  y) = compareInt#   x y
compareInteger (Jp# x)  (Jp# y) = compareBigNat x y
compareInteger (Jn# _)  _       = LT
compareInteger (S#  _)  (Jp# _) = LT
compareInteger (S#  _)  (Jn# _) = GT
compareInteger (Jp# _)  _       = GT
S#用于固定大小的整数,Jn#Jp#对于任意大小的整数。
在 GHC.Classes(来自 ghc-prim 包)中,我找到了 compareInt# 的定义。 .出现不寻常的类型,如 Int#示意我越来越近了。
compareInt# :: Int# -> Int# -> Ordering
compareInt# x# y#
    | isTrue# (x# <#  y#) = LT
    | isTrue# (x# ==# y#) = EQ
    | True                = GT
再深入一点,我得到了运算符的这个定义(GHC.Prim 模块)
infix 4 <#
(<#) :: Int# -> Int# -> Int#
(<#) = (<#)
但这是我能够得到的深度。 <#是指自己。我们不知道它在做什么。
(isTrue# 是一个简单的函数,“如果它的参数是 True,则返回 1#,如果 0# 则返回 False”)
我在哪里可以找到源头,工作完成的实际位置?
最底部是否有一些组件?我在哪里可以找到这个神圣的地方?

最佳答案

首先,技术上当你输入 GHC.Integer.Type模块你离开 Haskell 的领域并进入 GHC 使用的当前实现的领域,所以这个问题是关于 GHC Haskell 的。
所有原始操作,如 (<#)被实现为你在 GHC.Prim 中找到的递归循环。模块。从那里 the documentation告诉我们下一个要看的地方是 primops.txt.pp在名称下列出的文件 IntLtOp .
然后前面提到的文档说有两组primops:in-line和out-of-line。在从 STG 到 Cmm(这是 GHC 使用的两种内部表示)的转换过程中,内联 primops 被解析,可以在 GHC.StgToCmm.Prim 中找到。模块。确实the IntLtOp case is listed there它主要使用 mo_wordSLt 在线转换取决于平台的功能。
这个 mo_wordSLt 函数定义在 GHC.Cmm.MachOp包含引用的模块:

Machine-level primops; ones which we can reasonably delegate to the native code generators to handle.

mo_wordSLt函数产生 MO_S_Lt MachOp 的构造函数数据类型。因此,我们可以进一步研究 native 代码生成器,看看它是如何转换为低级指令的。平台有很多选择:SPARC , AArch64 , LLVM , C , PPC , 和 X86 (我在 GitLab 上通过搜索功能找到了所有这些)。
X86 是最受欢迎的平台,所以我将继续在那里。该实现使用 condIntReg 辅助函数,定义如下:
condIntReg :: Cond -> CmmExpr -> CmmExpr -> NatM Register

condIntReg cond x y = do
  CondCode _ cond cond_code <- condIntCode cond x y
  tmp <- getNewRegNat II8
  let
        code dst = cond_code `appOL` toOL [
                    SETCC cond (OpReg tmp),
                    MOVZxL II8 (OpReg tmp) (OpReg dst)
                  ]
  return (Any II32 code)
condIntCode 的定义也很有趣。 ,这取决于条件的操作数。这是一个很大的函数,所以我不会在这里重现完整的代码,但一般情况下会产生 CMP操作说明:
-- anything vs anything
condIntCode' _ cond x y = do
  platform <- getPlatform
  (y_reg, y_code) <- getNonClobberedReg y
  (x_op, x_code) <- getRegOrMem x
  let
        code = y_code `appOL`
               x_code `snocOL`
                  CMP (cmmTypeFormat (cmmExprType platform x)) (OpReg y_reg) x_op
  return (CondCode False cond code)

关于haskell - GHC 中如何实现整数比较?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69864238/

相关文章:

exception - 为什么Haskell中的()是Enum类型却没有实现succ函数

Haskell 高阶函数和结合性

haskell - 我应该在 Turtle 或 Foldl 包中使用折叠吗?

haskell - 意外的重叠实例错误

haskell - 找出多个互斥的、可能不终止的 Bool 中的哪一个是 True

windows - 如何更改ghc的路径?

haskell - ApplicativeDo 语言扩展 `Parsing` applicative 仍在寻找 Monad 实例

haskell - 使用此 GADT : 进行长度模式匹配

haskell - Haskell 中的树构建函数(作业)

haskell - 为什么GHC 与gcc 和g++ 一起发布?