起初,我想看看是如何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#,則回傳,如果是,則回傳False 0#”)
我在哪里可以找到來源,完成作業的實際地點?在最底部有一些組件嗎?我在哪里可以找到這個神圣的地方?
uj5u.com熱心網友回復:
首先,技術上當你進入GHC.Integer.Type模塊時,你離開了Haskell的領域,進入了GHC使用的當前實作的領域,所以這個問題是專門關于GHC Haskell的。
所有的原始操作(<#)都作為您在GHC.Prim模塊中找到的遞回回圈來實作。從那里檔案告訴我們下一個要查找的位置是primops.txt.pp它在名稱下列出的檔案IntLtOp。
然后前面提到的檔案說有兩組primops:in-line和out-of-line。在從 STG 到 Cmm(這是 GHC 使用的兩種內部表示)的轉換程序中決議了行內 primop,并且可以在GHC.StgToCmm.Prim模塊中找到。并且確實在IntLtOp那里列出了案例,并且主要使用mo_wordSLt取決于平臺的功能對其進行了在線轉換。
此mo_wordSLt函式在GHC.Cmm.MachOp包含參考的模塊中定義:
機器級primops;我們可以合理地委托給本機代碼生成器來處理的那些。
該mo_wordSLt函式生成資料型別的MO_S_Lt構造函式MachOp。所以我們可以進一步研究原生代碼生成器,看看它是如何轉換成低級指令的。平臺有很多選擇: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)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/352619.html
