1
1
{-|
2
2
Copyright : (C) 2013-2016, University of Twente,
3
3
2016-2017, Myrtle Software Ltd,
4
- 2017 , QBayLogic , Google Inc.,
5
- 2021 -2022, QBayLogic B.V.
4
+ 2017-2022 , Google Inc.,
5
+ 2017 -2022, QBayLogic B.V.
6
6
License : BSD2 (see the file LICENSE)
7
7
Maintainer : QBayLogic B.V. <[email protected] >
8
8
-}
@@ -20,6 +20,7 @@ module Clash.GHC.Evaluator.Primitive
20
20
( ghcPrimStep
21
21
, ghcPrimUnwind
22
22
, isUndefinedPrimVal
23
+ , isUndefinedXPrimVal
23
24
) where
24
25
25
26
import Control.Concurrent.Supply (Supply ,freshId )
@@ -88,15 +89,16 @@ import Clash.Core.Name
88
89
import Clash.Core.Pretty (showPpr )
89
90
import Clash.Core.Term
90
91
(IsMultiPrim (.. ), Pat (.. ), PrimInfo (.. ), Term (.. ), WorkInfo (.. ), mkApps ,
91
- PrimUnfolding (.. ))
92
+ PrimUnfolding (.. ), collectArgs )
92
93
import Clash.Core.Type
93
94
(Type (.. ), ConstTy (.. ), LitTy (.. ), TypeView (.. ), mkFunTy , mkTyConApp ,
94
95
splitFunForallTy , tyView )
95
96
import Clash.Core.TyCon
96
97
(TyConMap , TyConName , tyConDataCons )
97
98
import Clash.Core.TysPrim
98
99
import Clash.Core.Util
99
- (mkRTree ,mkVec ,tyNatSize ,dataConInstArgTys ,primCo , mkSelectorCase ,undefinedPrims )
100
+ (mkRTree ,mkVec ,tyNatSize ,dataConInstArgTys ,primCo , mkSelectorCase ,undefinedPrims ,
101
+ undefinedXPrims )
100
102
import Clash.Core.Var (mkLocalId , mkTyVar )
101
103
import Clash.Debug
102
104
import Clash.GHC.GHC2Core (modNameM )
@@ -124,6 +126,11 @@ isUndefinedPrimVal (PrimVal (PrimInfo{primName}) _ _) =
124
126
primName `elem` undefinedPrims
125
127
isUndefinedPrimVal _ = False
126
128
129
+ isUndefinedXPrimVal :: Value -> Bool
130
+ isUndefinedXPrimVal (PrimVal (PrimInfo {primName}) _ _) =
131
+ primName `elem` undefinedXPrims
132
+ isUndefinedXPrimVal _ = False
133
+
127
134
-- | Evaluation of primitive operations.
128
135
ghcPrimUnwind :: PrimUnwind
129
136
ghcPrimUnwind tcm p tys vs v [] m
@@ -132,6 +139,7 @@ ghcPrimUnwind tcm p tys vs v [] m
132
139
, Text. pack (show 'NP. removedArg)
133
140
, " GHC.Prim.MutableByteArray#"
134
141
, Text. pack (show 'NP. undefined )
142
+ , Text. pack (show 'NP. undefinedX)
135
143
]
136
144
-- The above primitives are actually values, and not operations.
137
145
= ghcUnwind (PrimVal p tys (vs ++ [v])) m tcm
@@ -160,10 +168,18 @@ ghcPrimUnwind tcm p tys vs v [] m
160
168
tmArgs = map (Left . valToTerm) (vs ++ [v])
161
169
in Just $ flip setTerm m $ TyApp (Prim NP. undefined ) $
162
170
applyTypeToArgs (Prim p) tcm (primType p) (tyArgs ++ tmArgs)
171
+ | isUndefinedXPrimVal v
172
+ = let tyArgs = map Right tys
173
+ tmArgs = map (Left . valToTerm) (vs ++ [v])
174
+ in Just $ flip setTerm m $ TyApp (Prim NP. undefinedX) $
175
+ applyTypeToArgs (Prim p) tcm (primType p) (tyArgs ++ tmArgs)
163
176
| otherwise
164
177
= ghcPrimStep tcm (forcePrims m) p tys (vs ++ [v]) m
165
178
166
179
ghcPrimUnwind tcm p tys vs v [e] m0
180
+ -- Note [Lazy primitives]
181
+ -- ~~~~~~~~~~~~~~~~~~~~~~
182
+ --
167
183
-- Primitives are usually considered undefined when one of their arguments is
168
184
-- (unless they're unused). _Some_ primitives can still yield a result even
169
185
-- though one of their arguments is undefined. It turns out that all primitives
@@ -174,6 +190,7 @@ ghcPrimUnwind tcm p tys vs v [e] m0
174
190
, " Clash.Sized.Vector.replace_int"
175
191
, " GHC.Classes.&&"
176
192
, " GHC.Classes.||"
193
+ , " Clash.Class.BitPack.Internal.xToBV"
177
194
]
178
195
= if isUndefinedPrimVal v then
179
196
let tyArgs = map Right tys
@@ -1585,6 +1602,11 @@ ghcPrimStep tcm isSubj pInfo tys args mach = case primName pInfo of
1585
1602
| [Lit (NaturalLiteral n), _] <- args
1586
1603
-> reduce (Literal (NaturalLiteral n))
1587
1604
1605
+ " GHC.TypeNats.someNatVal"
1606
+ | [Lit (NaturalLiteral n)] <- args
1607
+ -> let resTy = getResultTy tcm ty tys
1608
+ in reduce (mkSomeNat tcm n resTy)
1609
+
1588
1610
" GHC.Int.I8#"
1589
1611
| isSubj
1590
1612
, [Lit (IntLiteral i)] <- args
@@ -1790,6 +1812,29 @@ ghcPrimStep tcm isSubj pInfo tys args mach = case primName pInfo of
1790
1812
val = unpack (toBV i :: BitVector 64 )
1791
1813
in reduce (mkDoubleCLit tcm val resTy)
1792
1814
1815
+ " Clash.Class.BitPack.Internal.xToBV"
1816
+ | isSubj
1817
+ , Just (nTy, kn) <- extractKnownNat tcm tys
1818
+ -- The second argument to `xToBV` is always going to be suspended.
1819
+ -- See Note [Lazy primitives]
1820
+ , [ _, (Suspend arg) ] <- args
1821
+ , eval <- Evaluator ghcStep ghcUnwind ghcPrimStep ghcPrimUnwind
1822
+ , mach1@ Machine {mStack= [] ,mTerm= argWHNF} <-
1823
+ whnf eval tcm True (setTerm arg (stackClear mach))
1824
+ , let undefBitVector =
1825
+ Just $ mach1
1826
+ { mStack = mStack mach
1827
+ , mTerm = mkBitVectorLit ty nTy kn (bit (fromInteger kn)- 1 ) 0
1828
+ }
1829
+ -> case isX argWHNF of
1830
+ Left _ -> undefBitVector
1831
+ _ -> case collectArgs argWHNF of
1832
+ (Prim p,_) | primName p `elem` undefinedXPrims -> undefBitVector
1833
+ _ -> Just $ mach1
1834
+ { mStack = mStack mach
1835
+ , mTerm = argWHNF
1836
+ }
1837
+
1793
1838
-- expIndex#
1794
1839
-- :: KnownNat m
1795
1840
-- => Index m
@@ -4213,6 +4258,31 @@ mkDoubleCLit tcm lit resTy =
4213
4258
(Just doubleTc) = lookupUniqMap doubleTcNm tcm
4214
4259
[doubleDc] = tyConDataCons doubleTc
4215
4260
4261
+ mkSomeNat :: TyConMap -> Integer -> Type -> Term
4262
+ mkSomeNat tcm lit resTy =
4263
+ mkApps (Data someNatDc)
4264
+ [ Right (LitTy (NumTy lit))
4265
+ , Left (Literal (NaturalLiteral lit))
4266
+ , Left proxy
4267
+ ]
4268
+ where
4269
+ -- Get the SomeNat data constructor
4270
+ TyConApp someNatTcNm [] = tyView resTy
4271
+ (Just someNatTc) = lookupUniqMap someNatTcNm tcm
4272
+ [someNatDc] = tyConDataCons someNatTc
4273
+
4274
+ -- Get the Proxy data constructor
4275
+ (_: _: Right (tyView -> TyConApp proxyTcNm [natTy,_]): _,_) =
4276
+ splitFunForallTy (dcType someNatDc)
4277
+ (Just proxyTc) = lookupUniqMap proxyTcNm tcm
4278
+ [proxyDc] = tyConDataCons proxyTc
4279
+
4280
+ -- Build the Proxy argument
4281
+ proxy = mkApps (Data proxyDc)
4282
+ [ Right natTy
4283
+ , Right (LitTy (NumTy lit))
4284
+ ]
4285
+
4216
4286
-- From an argument list to function of type
4217
4287
-- forall n. KnownNat n => ...
4218
4288
-- extract (nTy,nInt)
0 commit comments