From d0334fc6e282a9789fea243947678dee2d5cd572 Mon Sep 17 00:00:00 2001 From: Dougal Date: Wed, 15 May 2024 14:05:17 -0400 Subject: [PATCH] Represent the huge pile of first-order ops as a simple functor. --- dex.cabal | 1 - src/lib/AbstractSyntax.hs | 4 +- src/lib/Builder.hs | 9 +- src/lib/CheapReduction.hs | 26 +-- src/lib/Core.hs | 2 +- src/lib/Imp.hs | 18 +-- src/lib/Inference.hs | 42 ++--- src/lib/QueryType.hs | 2 +- src/lib/QueryTypePure.hs | 78 ++++----- src/lib/Simplify.hs | 55 ++----- src/lib/Types/Core.hs | 312 +----------------------------------- src/lib/Types/OpNames.hs | 126 --------------- src/lib/Types/Primitives.hs | 133 ++++++++++++++- src/lib/Types/Source.hs | 54 ++++--- 14 files changed, 257 insertions(+), 605 deletions(-) delete mode 100644 src/lib/Types/OpNames.hs diff --git a/dex.cabal b/dex.cabal index 3d5b074c2..0f688fce5 100644 --- a/dex.cabal +++ b/dex.cabal @@ -86,7 +86,6 @@ library , Types.Core , Types.Imp , Types.Primitives - , Types.OpNames , Types.Source , Types.Top , QueryType diff --git a/src/lib/AbstractSyntax.hs b/src/lib/AbstractSyntax.hs index 7e680f23a..f726357e2 100644 --- a/src/lib/AbstractSyntax.hs +++ b/src/lib/AbstractSyntax.hs @@ -60,8 +60,8 @@ import Err import Name import PPrint import Types.Primitives +import qualified Types.Source as S import Types.Source -import qualified Types.OpNames as P import Util -- === Converting concrete syntax to abstract syntax === @@ -521,7 +521,7 @@ charExpr :: Char -> (UExpr' VoidS) charExpr c = ULit $ Word8Lit $ fromIntegral $ fromEnum c unitExpr :: SrcId -> UExpr VoidS -unitExpr sid = WithSrcE sid $ UPrim (UCon $ P.ProdCon) [] +unitExpr sid = WithSrcE sid $ UPrim (UCon $ S.ProdCon) [] -- === Builders === diff --git a/src/lib/Builder.hs b/src/lib/Builder.hs index b60ecae25..a850cfc07 100644 --- a/src/lib/Builder.hs +++ b/src/lib/Builder.hs @@ -34,7 +34,7 @@ import QueryType import Types.Core import Types.Imp import Types.Primitives -import Types.Source +import Types.Source hiding (TCName (..), ConName (..)) import Types.Top import Util (enumerate, transitiveClosureM, bindM2, toSnocList, popList) @@ -51,7 +51,6 @@ instance ToExpr (Expr r) r where toExpr = id instance ToExpr (Atom r) r where toExpr = Atom instance ToExpr (Con r) r where toExpr = Atom . Con instance ToExpr (AtomVar r) r where toExpr = toExpr . toAtom -instance IRRep r => ToExpr (MemOp r) r where toExpr op = PrimOp (getType op) (MemOp op) instance ToExpr (TypedHof r) r where toExpr = Hof -- === Ordinary (local) builder class === @@ -102,7 +101,7 @@ emitBinOp :: (Builder r m, Emits n) => BinOp -> Atom r n -> Atom r n -> m n (Ato emitBinOp op x y = emit $ PrimOp resultTy $ BinOp op x y where resultTy = TyCon $ BaseType $ typeBinOp op $ getTypeBaseType x -emitRefOp :: (Builder r m, Emits n) => Atom r n -> RefOp r n -> m n (Atom r n) +emitRefOp :: (Builder r m, Emits n) => Atom r n -> RefOp r (Atom r n) -> m n (Atom r n) emitRefOp ref op = undefined emitToVar :: (Builder r m, ToExpr e r, Emits n) => e n -> m n (AtomVar r n) @@ -1092,11 +1091,11 @@ naryIndexRef ref is = foldM indexRef ref is ptrOffset :: (Builder r m, Emits n) => Atom r n -> Atom r n -> m n (Atom r n) ptrOffset x (IdxRepVal 0) = return x -ptrOffset x i = emit $ PtrOffset x i +ptrOffset x i = undefined -- emit $ PtrOffset x i {-# INLINE ptrOffset #-} unsafePtrLoad :: (Builder r m, Emits n) => Atom r n -> m n (Atom r n) -unsafePtrLoad x = emit . PtrLoad =<< sinkM x +unsafePtrLoad x = undefined -- emit . PtrLoad =<< sinkM x mkIndexRef :: (EnvReader m, Fallible1 m, IRRep r) => Atom r n -> Atom r n -> m n (Expr r n) mkIndexRef ref i = do diff --git a/src/lib/CheapReduction.hs b/src/lib/CheapReduction.hs index 130597eb2..47e94f4cb 100644 --- a/src/lib/CheapReduction.hs +++ b/src/lib/CheapReduction.hs @@ -337,11 +337,6 @@ visitAlt (Abs b body) = do LamExpr (UnaryNest b') body' -> return $ Abs b' body' _ -> error "not an alt" -traverseOpTerm - :: (GenericOp e, Visitor m r i o, OpConst e r ~ OpConst e r) - => e r i -> m (e r o) -traverseOpTerm e = traverseOp e visitGeneric visitGeneric - visitTypeDefault :: (IRRep r, Visitor (m i o) r i o, AtomSubstReader v m, EnvReader2 m) => Type r i -> m i o (Type r o) @@ -392,22 +387,13 @@ instance IRRep r => VisitGeneric (Expr r) r where return $ Case x' alts' effTy' Atom x -> Atom <$> visitGeneric x TabCon t xs -> TabCon <$> visitGeneric t <*> mapM visitGeneric xs - PrimOp t op -> PrimOp <$> visitGeneric t <*> visitGeneric op + PrimOp t op -> PrimOp <$> visitGeneric t <*> mapM visitGeneric op App et fAtom xs -> App <$> visitGeneric et <*> visitGeneric fAtom <*> mapM visitGeneric xs ApplyMethod et m i xs -> ApplyMethod <$> visitGeneric et <*> visitGeneric m <*> pure i <*> mapM visitGeneric xs Project t i x -> Project <$> visitGeneric t <*> pure i <*> visitGeneric x Unwrap t x -> Unwrap <$> visitGeneric t <*> visitGeneric x Hof op -> Hof <$> visitGeneric op -instance IRRep r => VisitGeneric (PrimOp r) r where - visitGeneric = \case - UnOp op x -> UnOp op <$> visitGeneric x - BinOp op x y -> BinOp op <$> visitGeneric x <*> visitGeneric y - MemOp op -> MemOp <$> visitGeneric op - VectorOp op -> VectorOp <$> visitGeneric op - MiscOp op -> MiscOp <$> visitGeneric op - RefOp r op -> RefOp <$> visitGeneric r <*> traverseOp op visitGeneric visitGeneric - instance IRRep r => VisitGeneric (TypedHof r) r where visitGeneric (TypedHof eff hof) = TypedHof <$> visitGeneric eff <*> visitGeneric hof @@ -536,10 +522,6 @@ instance IRRep r => VisitGeneric (Dict r) r where StuckDict ty s -> fromJust <$> toMaybeDict <$> visitGeneric (Stuck ty s) DictCon con -> DictCon <$> visitGeneric con -instance VisitGeneric (MiscOp r) r where visitGeneric = traverseOpTerm -instance VisitGeneric (VectorOp r) r where visitGeneric = traverseOpTerm -instance VisitGeneric (MemOp r) r where visitGeneric = traverseOpTerm - -- === SubstE/SubstB instances === -- These live here, as orphan instances, because we normalize as we substitute. @@ -631,14 +613,8 @@ instance IRRep r => SubstE AtomSubstVal (Hof r) instance IRRep r => SubstE AtomSubstVal (TyCon r) instance IRRep r => SubstE AtomSubstVal (DictCon r) instance IRRep r => SubstE AtomSubstVal (Con r) -instance IRRep r => SubstE AtomSubstVal (MiscOp r) -instance IRRep r => SubstE AtomSubstVal (VectorOp r) -instance IRRep r => SubstE AtomSubstVal (MemOp r) -instance IRRep r => SubstE AtomSubstVal (PrimOp r) -instance IRRep r => SubstE AtomSubstVal (RefOp r) instance IRRep r => SubstE AtomSubstVal (EffTy r) instance IRRep r => SubstE AtomSubstVal (Expr r) -instance IRRep r => SubstE AtomSubstVal (GenericOpRep const r) instance SubstE AtomSubstVal InstanceBody instance SubstE AtomSubstVal DictType instance IRRep r => SubstE AtomSubstVal (LamExpr r) diff --git a/src/lib/Core.hs b/src/lib/Core.hs index bfa6db8e0..cc690cefe 100644 --- a/src/lib/Core.hs +++ b/src/lib/Core.hs @@ -40,7 +40,7 @@ import Types.Core import Types.Top import Types.Imp import Types.Primitives -import Types.Source +import Types.Source hiding (ProdCon, ProdType) -- === Typeclasses for monads === diff --git a/src/lib/Imp.hs b/src/lib/Imp.hs index e09298597..9deaab983 100644 --- a/src/lib/Imp.hs +++ b/src/lib/Imp.hs @@ -320,10 +320,10 @@ translateExpr expr = confuseGHC >>= \_ -> case expr of Hof hof -> toImpTypedHof hof toImpRefOp :: Emits o - => SAtom i -> RefOp SimpIR i -> SubstImpM i o (SAtom o) + => SAtom i -> RefOp SimpIR (SAtom i) -> SubstImpM i o (SAtom o) toImpRefOp refDest' m = do refDest <- atomToDest =<< substM refDest' - substM m >>= \case + mapM substM m >>= \case MPut x -> storeAtom refDest x >> return UnitVal MGet -> do Dest resultTy _ <- return refDest @@ -335,23 +335,23 @@ toImpRefOp refDest' m = do IndexRef i -> destToAtom <$> indexDest refDest i ProjRef ~(ProjectProduct i) -> return $ destToAtom $ projectDest i refDest -toImpOp :: forall i o . Emits o => SType i -> PrimOp SimpIR i -> SubstImpM i o (SAtom o) +toImpOp :: forall i o . Emits o => SType i -> PrimOp SimpIR (SAtom i) -> SubstImpM i o (SAtom o) toImpOp resultTy op = case op of RefOp refDest eff -> toImpRefOp refDest eff BinOp binOp x y -> returnIExprVal =<< emitInstr =<< (IBinOp binOp <$> fsa x <*> fsa y) UnOp unOp x -> returnIExprVal =<< emitInstr =<< (IUnOp unOp <$> fsa x) - MemOp op' -> toImpMemOp =<< substM op' + MemOp op' -> toImpMemOp =<< mapM substM op' MiscOp op' -> do resultTy' <- substM resultTy - toImpMiscOp resultTy' =<< substM op' + toImpMiscOp resultTy' =<< mapM substM op' VectorOp op' -> do resultTy' <- substM resultTy - toImpVectorOp resultTy' =<< substM op' + toImpVectorOp resultTy' =<< mapM substM op' where fsa x = substM x >>= fromScalarAtom returnIExprVal x = return $ toScalarAtom x -toImpVectorOp :: Emits o => SType o -> VectorOp SimpIR o -> SubstImpM i o (SAtom o) +toImpVectorOp :: Emits o => SType o -> VectorOp SimpIR (SAtom o) -> SubstImpM i o (SAtom o) toImpVectorOp vty = \case VectorBroadcast val -> do val' <- fromScalarAtom val @@ -373,7 +373,7 @@ castPtrToVectorType ptr vty = do let PtrType (addrSpace, _) = getIType ptr cast ptr (PtrType (addrSpace, vty)) -toImpMiscOp :: forall i o . Emits o => SType o -> MiscOp SimpIR o -> SubstImpM i o (SAtom o) +toImpMiscOp :: forall i o . Emits o => SType o -> MiscOp SimpIR (SAtom o) -> SubstImpM i o (SAtom o) toImpMiscOp resultTy op = case op of ThrowError -> do emitStatement IThrowError @@ -424,7 +424,7 @@ toImpMiscOp resultTy op = case op of fsa = fromScalarAtom returnIExprVal x = return $ toScalarAtom x -toImpMemOp :: forall i o . Emits o => MemOp SimpIR o -> SubstImpM i o (SAtom o) +toImpMemOp :: forall i o . Emits o => MemOp SimpIR (SAtom o) -> SubstImpM i o (SAtom o) toImpMemOp op = case op of IOAlloc n -> do n' <- fsa n diff --git a/src/lib/Inference.hs b/src/lib/Inference.hs index 22a55b40b..ee7e0352e 100644 --- a/src/lib/Inference.hs +++ b/src/lib/Inference.hs @@ -42,9 +42,9 @@ import QueryType import Types.Core import Types.Imp import Types.Primitives -import Types.Source +import qualified Types.Source as S +import Types.Source hiding (ConName (..), TCName (..)) import Types.Top -import qualified Types.OpNames as P import Util hiding (group) -- === Top-level interface === @@ -1030,13 +1030,13 @@ matchPrimApp = \case UBaseType b -> \case ~[] -> return $ toAtomR $ BaseType b UNatCon -> \case ~[x] -> return $ toAtom $ NewtypeCon NatCon x UPrimTC tc -> case tc of - P.ProdType -> \ts -> return $ toAtom $ ProdType $ map (fromJust . toMaybeType) ts - P.SumType -> \ts -> return $ toAtom $ SumType $ map (fromJust . toMaybeType) ts - P.RefType -> \case ~[h, a] -> undefined -- return $ toAtom $ RefType h (fromJust $ toMaybeType a) - P.TypeKind -> \case ~[] -> return $ toAtom $ Kind $ TypeKind + S.ProdType -> \ts -> return $ toAtom $ ProdType $ map (fromJust . toMaybeType) ts + S.SumType -> \ts -> return $ toAtom $ SumType $ map (fromJust . toMaybeType) ts + S.RefType -> \case ~[h, a] -> undefined -- return $ toAtom $ RefType h (fromJust $ toMaybeType a) + S.TypeKind -> \case ~[] -> return $ toAtom $ Kind $ TypeKind UCon con -> case con of - P.ProdCon -> \xs -> return $ toAtom $ ProdCon xs - P.SumCon _ -> error "not supported" + S.ProdCon -> \xs -> return $ toAtom $ ProdCon xs + S.SumCon _ -> error "not supported" -- UMiscOp op -> \x -> emit =<< MiscOp <$> matchGenericOp op x -- UMemOp op -> \x -> emit =<< MemOp <$> matchGenericOp op x UBinOp op -> \case ~[x, y] -> emitBinOp op x y @@ -1059,19 +1059,19 @@ matchPrimApp = \case ExplicitCoreLam (UnaryNest b) body <- return x return $ UnaryLamExpr b body - matchGenericOp :: GenericOp op => OpConst op CoreIR -> [CAtom n] -> InfererM i n (op CoreIR n) - matchGenericOp op xs = do - (tyArgs, dataArgs) <- partitionEithers <$> forM xs \x -> do - case getType x of - TyCon (Kind TypeKind) -> do - Just x' <- return $ toMaybeType x - return $ Left x' - _ -> return $ Right x - let tyArgs' = case tyArgs of - [] -> Nothing - [t] -> Just t - _ -> error "Expected at most one type arg" - return $ fromJust $ toOp $ GenericOpRep op tyArgs' dataArgs + -- matchGenericOp :: GenericOp op => OpConst op CoreIR -> [CAtom n] -> InfererM i n (op CoreIR n) + -- matchGenericOp op xs = do + -- (tyArgs, dataArgs) <- partitionEithers <$> forM xs \x -> do + -- case getType x of + -- TyCon (Kind TypeKind) -> do + -- Just x' <- return $ toMaybeType x + -- return $ Left x' + -- _ -> return $ Right x + -- let tyArgs' = case tyArgs of + -- [] -> Nothing + -- [t] -> Just t + -- _ -> error "Expected at most one type arg" + -- return $ fromJust $ toOp $ GenericOpRep op tyArgs' dataArgs pattern ExplicitCoreLam :: Nest CBinder n l -> CExpr l -> CAtom n pattern ExplicitCoreLam bs body <- Con (Lam (CoreLamExpr _ (LamExpr bs body))) diff --git a/src/lib/QueryType.hs b/src/lib/QueryType.hs index 1579bcbd1..bbed09e24 100644 --- a/src/lib/QueryType.hs +++ b/src/lib/QueryType.hs @@ -15,7 +15,7 @@ import Data.Functor ((<&>)) import Types.Primitives import Types.Core -import Types.Source +import Types.Source hiding (TCName (..)) import Types.Top import Types.Imp import IRVariants diff --git a/src/lib/QueryTypePure.hs b/src/lib/QueryTypePure.hs index a2dfdf903..d133a094c 100644 --- a/src/lib/QueryTypePure.hs +++ b/src/lib/QueryTypePure.hs @@ -150,15 +150,15 @@ getTypeBaseType e = case getType e of TyCon (BaseType b) -> b ty -> error $ "Expected a base type. Got: " ++ show ty -instance IRRep r => HasType r (MemOp r) where - getType = \case - IOAlloc _ -> PtrTy (CPU, Scalar Word8Type) - IOFree _ -> UnitTy - PtrOffset arr _ -> getType arr - PtrLoad ptr -> do - let PtrTy (_, t) = getType ptr - toType $ BaseType t - PtrStore _ _ -> UnitTy +-- instance IRRep r => HasType r (MemOp r) where +-- getType = \case +-- IOAlloc _ -> PtrTy (CPU, Scalar Word8Type) +-- IOFree _ -> UnitTy +-- PtrOffset arr _ -> getType arr +-- PtrLoad ptr -> do +-- let PtrTy (_, t) = getType ptr +-- toType $ BaseType t +-- PtrStore _ _ -> UnitTy rawStrType :: IRRep r => Type r n rawStrType = case newName "n" of @@ -216,7 +216,7 @@ instance IRRep r => HasEffects (Expr r) r where Case _ _ (EffTy effs _) -> effs TabCon _ _ -> Pure ApplyMethod (EffTy eff _) _ _ _ -> eff - PrimOp _ primOp -> getEffects primOp + -- PrimOp _ primOp -> getEffects primOp Project _ _ _ -> Pure Unwrap _ _ -> Pure Hof (TypedHof (EffTy eff _) _) -> eff @@ -225,32 +225,32 @@ instance IRRep r => HasEffects (DeclBinding r) r where getEffects (DeclBinding _ expr) = getEffects expr {-# INLINE getEffects #-} -instance IRRep r => HasEffects (PrimOp r) r where - getEffects = \case - UnOp _ _ -> Pure - BinOp _ _ _ -> Pure - VectorOp _ -> Pure - MemOp op -> case op of - IOAlloc _ -> Effectful - IOFree _ -> Effectful - PtrLoad _ -> Effectful - PtrStore _ _ -> Effectful - PtrOffset _ _ -> Pure - MiscOp op -> case op of - Select _ _ _ -> Pure - ThrowError -> Pure - CastOp _ -> Pure - UnsafeCoerce _ -> Pure - GarbageVal -> Pure - BitcastOp _ -> Pure - SumTag _ -> Pure - ToEnum _ -> Pure - OutputStream -> Pure - ShowAny _ -> Pure - ShowScalar _ -> Pure - RefOp _ m -> case m of - MGet -> Effectful - MPut _ -> Effectful - IndexRef _ -> Pure - ProjRef _ -> Pure - {-# INLINE getEffects #-} +-- instance IRRep r => HasEffects (PrimOp r) r where +-- getEffects = \case +-- UnOp _ _ -> Pure +-- BinOp _ _ _ -> Pure +-- VectorOp _ -> Pure +-- MemOp op -> case op of +-- IOAlloc _ -> Effectful +-- IOFree _ -> Effectful +-- PtrLoad _ -> Effectful +-- PtrStore _ _ -> Effectful +-- PtrOffset _ _ -> Pure +-- MiscOp op -> case op of +-- Select _ _ _ -> Pure +-- ThrowError -> Pure +-- CastOp _ -> Pure +-- UnsafeCoerce _ -> Pure +-- GarbageVal -> Pure +-- BitcastOp _ -> Pure +-- SumTag _ -> Pure +-- ToEnum _ -> Pure +-- OutputStream -> Pure +-- ShowAny _ -> Pure +-- ShowScalar _ -> Pure +-- RefOp _ m -> case m of +-- MGet -> Effectful +-- MPut _ -> Effectful +-- IndexRef _ -> Pure +-- ProjRef _ -> Pure +-- {-# INLINE getEffects #-} diff --git a/src/lib/Simplify.hs b/src/lib/Simplify.hs index 6359b1b98..45e1d94f1 100644 --- a/src/lib/Simplify.hs +++ b/src/lib/Simplify.hs @@ -221,7 +221,6 @@ simplifyExpr = \case f' <- toDataAtom f simplifyTabApp f' x' Atom x -> simplifyAtom x - PrimOp _ op -> simplifyOp op Hof (TypedHof (EffTy _ ty) hof) -> simplifyHof hof ApplyMethod (EffTy _ ty) dict i xs -> do xs' <- mapM simplifyAtom xs @@ -247,25 +246,22 @@ simplifyExpr = \case x' <- toDataAtom x SimpAtom <$> proj i x' Unwrap _ x -> SimpAtom <$> toDataAtom x + PrimOp _ (RefOp ref (ProjRef UnwrapNewtype)) -> SimpAtom <$> toDataAtom ref + PrimOp ty op -> do + ty' <- getRepType ty + op' <- mapM toDataAtom op + let op'' = changeIR op' + SimpAtom <$> emit (PrimOp ty' op'') + +-- Use this if you've handled all the cases that occur in `r` but not `r'` +changeIR :: PrimOp r a -> PrimOp r' a +changeIR = undefined requireReduced :: CExpr o -> SimplifyM i o (CAtom o) requireReduced expr = reduceExpr expr >>= \case Just x -> return x Nothing -> error "couldn't reduce expression" -simplifyRefOp :: Emits o => RefOp CoreIR i -> SAtom o -> SimplifyM i o (SAtom o) -simplifyRefOp op ref = case op of - MGet -> undefined -- emit $ RefOp ref MGet - MPut x -> do - x' <- toDataAtom x - emitRefOp $ MPut x' - IndexRef x -> do - x' <- toDataAtom x - emit =<< mkIndexRef ref x' - ProjRef (ProjectProduct i) -> emit =<< mkProjRef ref (ProjectProduct i) - ProjRef UnwrapNewtype -> return ref - where emitRefOp op' = undefined -- emit $ RefOp ref op' - simplifyApp :: Emits o => SimpVal o -> [SimpVal o] -> SimplifyM i o (SimpVal o) simplifyApp f xs = case f of SimpCCon (WithSubst s con) -> case con of @@ -407,37 +403,6 @@ simplifyLam (LamExpr bsTop body) = case bsTop of body' <- buildBlock $ fromSimpAtom <$> simplifyExpr body return $ LamExpr Empty body' -simplifyOp :: Emits o => PrimOp CoreIR i -> SimplifyM i o (SimpVal o) -simplifyOp op = case op of - MemOp op' -> simplifyGenericOp op' - VectorOp op' -> undefined -- simplifyGenericOp op' - RefOp ref eff -> do - ref' <- toDataAtom ref - SimpAtom <$> simplifyRefOp eff ref' - BinOp binop x y -> do - x' <- toDataAtom x - y' <- toDataAtom y - SimpAtom <$> emitBinOp binop x' y' - UnOp unOp x -> do - x' <- toDataAtom x - SimpAtom <$> emitUnOp unOp x' - MiscOp op' -> case op' of - ShowAny x -> undefined - -- ShowAny x -> do - -- x' <- toDataAtom x - -- dropSubst $ showAny x' >>= simplifyExpr - _ -> undefined -- simplifyGenericOp op' - -simplifyGenericOp - :: (GenericOp op, ToExpr (op SimpIR) SimpIR, HasType CoreIR (op CoreIR), Emits o, - OpConst op CoreIR ~ OpConst op SimpIR) - => op CoreIR i - -> SimplifyM i o (SimpVal o) -simplifyGenericOp op = do - op' <- traverseOp op getRepType toDataAtom - SimpAtom <$> emit op' -{-# INLINE simplifyGenericOp #-} - applyDictMethod :: Emits o => DictCon CoreIR i -> Int -> [SimpVal o] -> SimplifyM i o (SimpVal o) applyDictMethod d i methodArgs = case d of InstanceDict _ instanceName instanceArgs -> do diff --git a/src/lib/Types/Core.hs b/src/lib/Types/Core.hs index cb4ff668d..cbb539ee4 100644 --- a/src/lib/Types/Core.hs +++ b/src/lib/Types/Core.hs @@ -9,10 +9,9 @@ -- Core data types for CoreIR and its variations. -module Types.Core (module Types.Core, SymbolicZeros (..)) where +module Types.Core (module Types.Core) where import Data.Word -import Data.Maybe (fromJust) import Data.Foldable (toList) import Data.Hashable import Data.String (fromString) @@ -28,9 +27,8 @@ import Util (Tree (..)) import IRVariants import PPrint -import qualified Types.OpNames as P import Types.Primitives -import Types.Source +import Types.Source (HasSourceName (..)) import Types.Imp -- === core IR === @@ -109,7 +107,7 @@ data Expr r n where Case :: Atom r n -> [Alt r n] -> EffTy r n -> Expr r n Atom :: Atom r n -> Expr r n TabCon :: Type r n -> [Atom r n] -> Expr r n - PrimOp :: Type r n -> PrimOp r n -> Expr r n + PrimOp :: Type r n -> PrimOp r (Atom r n) -> Expr r n Hof :: TypedHof r n -> Expr r n Project :: Type r n -> Int -> Atom r n -> Expr r n App :: EffTy CoreIR n -> CAtom n -> [CAtom n] -> Expr CoreIR n @@ -252,100 +250,10 @@ instance ToBindersAbs TyConDef DataConDefs CoreIR where instance ToBindersAbs ClassDef (Abs (Nest CBinder) (ListE CorePiType)) CoreIR where toAbs (ClassDef _ _ _ _ _ bs scBs tys) = Abs bs (Abs scBs (ListE tys)) --- === GenericOp class === - -class GenericOp (e::IR->E) where - type OpConst e (r::IR) :: * - fromOp :: e r n -> GenericOpRep (OpConst e r) r n - toOp :: GenericOpRep (OpConst e r) r n -> Maybe (e r n) - -data GenericOpRep (const :: *) (r::IR) (n::S) = - GenericOpRep const (Maybe (Type r n)) [Atom r n] -- name, optional result type, args - deriving (Show, Generic) - -instance GenericE (GenericOpRep const r) where - type RepE (GenericOpRep const r) = LiftE const `PairE` MaybeE (Type r) `PairE` ListE (Atom r) - fromE (GenericOpRep c ts xs) = LiftE c `PairE` toMaybeE ts `PairE` ListE xs - {-# INLINE fromE #-} - toE (LiftE c `PairE` ts `PairE` ListE xs) = GenericOpRep c (fromMaybeE ts) xs - {-# INLINE toE #-} - -instance IRRep r => SinkableE (GenericOpRep const r) where -instance IRRep r => HoistableE (GenericOpRep const r) where -instance (Eq const, IRRep r) => AlphaEqE (GenericOpRep const r) -instance (Hashable const, IRRep r) => AlphaHashableE (GenericOpRep const r) -instance IRRep r => RenameE (GenericOpRep const r) where - renameE env (GenericOpRep c ts xs) = - GenericOpRep c (fmap (renameE env) ts) (map (renameE env) xs) - -fromEGenericOpRep :: GenericOp e => e r n -> GenericOpRep (OpConst e r) r n -fromEGenericOpRep = fromOp - -toEGenericOpRep :: GenericOp e => GenericOpRep (OpConst e r) r n -> e r n -toEGenericOpRep = fromJust . toOp - -traverseOp - :: (GenericOp e, Monad m, OpConst e r ~ OpConst e r') - => e r i - -> (Type r i -> m (Type r' o)) - -> (Atom r i -> m (Atom r' o)) - -> m (e r' o) -traverseOp op fType fAtom = do - let GenericOpRep c tys atoms = fromOp op - tys' <- mapM fType tys - atoms' <- mapM fAtom atoms - return $ fromJust $ toOp $ GenericOpRep c tys' atoms' - --- === Various ops === - -data PrimOp (r::IR) (n::S) where - UnOp :: P.UnOp -> Atom r n -> PrimOp r n - BinOp :: P.BinOp -> Atom r n -> Atom r n -> PrimOp r n - MemOp :: MemOp r n -> PrimOp r n - VectorOp :: VectorOp r n -> PrimOp r n - MiscOp :: MiscOp r n -> PrimOp r n - RefOp :: Atom r n -> RefOp r n -> PrimOp r n - -deriving instance IRRep r => Show (PrimOp r n) -deriving via WrapE (PrimOp r) n instance IRRep r => Generic (PrimOp r n) - -data MemOp (r::IR) (n::S) = - IOAlloc (Atom r n) - | IOFree (Atom r n) - | PtrOffset (Atom r n) (Atom r n) - | PtrLoad (Atom r n) - | PtrStore (Atom r n) (Atom r n) - deriving (Show, Generic) - -data MiscOp (r::IR) (n::S) = - Select (Atom r n) (Atom r n) (Atom r n) -- (3) predicate, val-if-true, val-if-false - | CastOp (Atom r n) -- (2) See CheckType.hs for valid coercions. - | BitcastOp (Atom r n) -- (2) See CheckType.hs for valid coercions. - | UnsafeCoerce (Atom r n) -- type, then value. Assumes runtime representation is the same. - | GarbageVal -- (TODO: redundant with NewRef) - | NewRef - | ThrowError - -- Tag of a sum type - | SumTag (Atom r n) - -- Create an enum (payload-free ADT) from a Word8 - | ToEnum (Atom r n) - -- printing - | OutputStream - | ShowAny (Atom r n) -- implemented in Simplify - | ShowScalar (Atom r n) -- Implemented in Imp. Result is a pair of an `IdxRepValTy` - -- giving the logical size of the result and a fixed-size table, - -- `Fin showStringBufferSize => Char`, assumed to have sufficient space. - deriving (Show, Generic) - showStringBufferSize :: Word32 showStringBufferSize = 32 -data VectorOp r n = - VectorBroadcast (Atom r n) -- value, - | VectorIota - | VectorIdx (Atom r n) (Atom r n) -- table, base ix - | VectorSubref (Atom r n) (Atom r n) -- ref, base ix - deriving (Show, Generic) +-- === Hofs === data TypedHof r n = TypedHof (EffTy r n) (Hof r n) deriving (Show, Generic) @@ -359,13 +267,6 @@ data Hof r n where deriving instance IRRep r => Show (Hof r n) deriving via WrapE (Hof r) n instance IRRep r => Generic (Hof r n) -data RefOp r n = - MGet - | MPut (Atom r n) - | IndexRef (Atom r n) - | ProjRef Projection - deriving (Show, Generic) - -- === IR variants === type CAtom = Atom CoreIR @@ -830,33 +731,6 @@ instance IRRep r => RenameE (Hof r) instance IRRep r => AlphaEqE (Hof r) instance IRRep r => AlphaHashableE (Hof r) -instance GenericOp RefOp where - type OpConst RefOp r = P.RefOp - fromOp = \case - MGet -> GenericOpRep P.MGet Nothing [] - MPut x -> GenericOpRep P.MPut Nothing [x] - IndexRef x -> GenericOpRep P.IndexRef Nothing [x] - ProjRef p -> GenericOpRep (P.ProjRef p) Nothing [] - {-# INLINE fromOp #-} - toOp = \case - GenericOpRep P.MGet Nothing [] -> Just $ MGet - GenericOpRep P.MPut Nothing [x] -> Just $ MPut x - GenericOpRep P.IndexRef Nothing [x] -> Just $ IndexRef x - GenericOpRep (P.ProjRef p) Nothing [] -> Just $ ProjRef p - _ -> Nothing - {-# INLINE toOp #-} - -instance IRRep r => GenericE (RefOp r) where - type RepE (RefOp r) = GenericOpRep (OpConst RefOp r) r - fromE = fromEGenericOpRep - toE = toEGenericOpRep - -instance IRRep r => SinkableE (RefOp r) -instance IRRep r => HoistableE (RefOp r) -instance IRRep r => RenameE (RefOp r) -instance IRRep r => AlphaEqE (RefOp r) -instance IRRep r => AlphaHashableE (RefOp r) - instance IRRep r => GenericE (Atom r) where type RepE (Atom r) = EitherE (PairE (Type r) (Stuck r)) (Con r) fromE = \case @@ -976,7 +850,7 @@ instance IRRep r => GenericE (Expr r) where ) ( EitherE6 {- TabCon -} (Type r `PairE` ListE (Atom r)) - {- PrimOp -} (Type r `PairE` PrimOp r) + {- PrimOp -} (Type r `PairE` ComposeE (PrimOp r) (Atom r)) {- ApplyMethod -} (WhenCore r (EffTy r `PairE` Atom r `PairE` LiftE Int `PairE` ListE (Atom r))) {- Project -} (Type r `PairE` LiftE Int `PairE` Atom r) {- Unwrap -} (WhenCore r (CType `PairE` CAtom)) @@ -989,7 +863,7 @@ instance IRRep r => GenericE (Expr r) where TopApp et f xs -> Case0 $ Case4 (WhenIRE (et `PairE` f `PairE` ListE xs)) Block et block -> Case0 $ Case5 (et `PairE` block) TabCon ty xs -> Case1 $ Case0 (ty `PairE` ListE xs) - PrimOp ty op -> Case1 $ Case1 (ty `PairE` op) + PrimOp ty op -> Case1 $ Case1 (ty `PairE` ComposeE op) ApplyMethod et d i xs -> Case1 $ Case2 (WhenIRE (et `PairE` d `PairE` LiftE i `PairE` ListE xs)) Project ty i x -> Case1 $ Case3 (ty `PairE` LiftE i `PairE` x) Unwrap t x -> Case1 $ Case4 (WhenIRE (t `PairE` x)) @@ -1006,7 +880,7 @@ instance IRRep r => GenericE (Expr r) where _ -> error "impossible" Case1 case1 -> case case1 of Case0 (ty `PairE` ListE xs) -> TabCon ty xs - Case1 (ty `PairE` op) -> PrimOp ty op + Case1 (ty `PairE` ComposeE op) -> PrimOp ty op Case2 (WhenIRE (et `PairE` d `PairE` LiftE i `PairE` ListE xs)) -> ApplyMethod et d i xs Case3 (ty `PairE` LiftE i `PairE` x) -> Project ty i x Case4 (WhenIRE (t `PairE` x)) -> Unwrap t x @@ -1021,136 +895,6 @@ instance IRRep r => AlphaEqE (Expr r) instance IRRep r => AlphaHashableE (Expr r) instance IRRep r => RenameE (Expr r) -instance IRRep r => GenericE (PrimOp r) where - type RepE (PrimOp r) = EitherE6 - {- UnOp -} (LiftE P.UnOp `PairE` Atom r) - {- BinOp -} (LiftE P.BinOp `PairE` Atom r `PairE` Atom r) - {- MemOp -} (MemOp r) - {- VectorOp -} (VectorOp r) - {- MiscOp -} (MiscOp r) - {- RefOp -} (Atom r `PairE` RefOp r) - fromE = \case - UnOp op x -> Case0 $ LiftE op `PairE` x - BinOp op x y -> Case1 $ LiftE op `PairE` x `PairE` y - MemOp op -> Case2 op - VectorOp op -> Case3 op - MiscOp op -> Case4 op - RefOp r op -> Case5 $ r `PairE` op - {-# INLINE fromE #-} - - toE = \case - Case0 (LiftE op `PairE` x ) -> UnOp op x - Case1 (LiftE op `PairE` x `PairE` y) -> BinOp op x y - Case2 op -> MemOp op - Case3 op -> VectorOp op - Case4 op -> MiscOp op - Case5 (r `PairE` op) -> RefOp r op - _ -> error "impossible" - {-# INLINE toE #-} - -instance IRRep r => SinkableE (PrimOp r) -instance IRRep r => HoistableE (PrimOp r) -instance IRRep r => AlphaEqE (PrimOp r) -instance IRRep r => AlphaHashableE (PrimOp r) -instance IRRep r => RenameE (PrimOp r) - -instance GenericOp VectorOp where - type OpConst VectorOp r = P.VectorOp - fromOp = \case - VectorBroadcast x -> GenericOpRep P.VectorBroadcast Nothing [x] - VectorIota -> GenericOpRep P.VectorIota Nothing [] - VectorIdx x y -> GenericOpRep P.VectorIdx Nothing [x, y] - VectorSubref x y -> GenericOpRep P.VectorSubref Nothing [x, y] - {-# INLINE fromOp #-} - - toOp = \case - GenericOpRep P.VectorBroadcast Nothing [x] -> Just $ VectorBroadcast x - GenericOpRep P.VectorIota Nothing [] -> Just $ VectorIota - GenericOpRep P.VectorIdx Nothing [x, y] -> Just $ VectorIdx x y - GenericOpRep P.VectorSubref Nothing [x, y] -> Just $ VectorSubref x y - _ -> Nothing - {-# INLINE toOp #-} - -instance IRRep r => GenericE (VectorOp r) where - type RepE (VectorOp r) = GenericOpRep (OpConst VectorOp r) r - fromE = fromEGenericOpRep - toE = toEGenericOpRep -instance IRRep r => SinkableE (VectorOp r) -instance IRRep r => HoistableE (VectorOp r) -instance IRRep r => AlphaEqE (VectorOp r) -instance IRRep r => AlphaHashableE (VectorOp r) -instance IRRep r => RenameE (VectorOp r) - -instance GenericOp MemOp where - type OpConst MemOp r = P.MemOp - fromOp = \case - IOAlloc x -> GenericOpRep P.IOAlloc Nothing [x] - IOFree x -> GenericOpRep P.IOFree Nothing [x] - PtrOffset x y -> GenericOpRep P.PtrOffset Nothing [x, y] - PtrLoad x -> GenericOpRep P.PtrLoad Nothing [x] - PtrStore x y -> GenericOpRep P.PtrStore Nothing [x, y] - {-# INLINE fromOp #-} - toOp = \case - GenericOpRep P.IOAlloc Nothing [x] -> Just $ IOAlloc x - GenericOpRep P.IOFree Nothing [x] -> Just $ IOFree x - GenericOpRep P.PtrOffset Nothing [x, y] -> Just $ PtrOffset x y - GenericOpRep P.PtrLoad Nothing [x] -> Just $ PtrLoad x - GenericOpRep P.PtrStore Nothing [x, y] -> Just $ PtrStore x y - _ -> Nothing - {-# INLINE toOp #-} - -instance IRRep r => GenericE (MemOp r) where - type RepE (MemOp r) = GenericOpRep (OpConst MemOp r) r - fromE = fromEGenericOpRep - toE = toEGenericOpRep -instance IRRep r => SinkableE (MemOp r) -instance IRRep r => HoistableE (MemOp r) -instance IRRep r => AlphaEqE (MemOp r) -instance IRRep r => AlphaHashableE (MemOp r) -instance IRRep r => RenameE (MemOp r) - -instance GenericOp MiscOp where - type OpConst MiscOp r = P.MiscOp - fromOp = \case - Select p x y -> GenericOpRep P.Select Nothing [p,x,y] - CastOp x -> GenericOpRep P.CastOp Nothing [x] - BitcastOp x -> GenericOpRep P.BitcastOp Nothing [x] - UnsafeCoerce x -> GenericOpRep P.UnsafeCoerce Nothing [x] - GarbageVal -> GenericOpRep P.GarbageVal Nothing [] - NewRef -> GenericOpRep P.NewRef Nothing [] - ThrowError -> GenericOpRep P.ThrowError Nothing [] - SumTag x -> GenericOpRep P.SumTag Nothing [x] - ToEnum x -> GenericOpRep P.ToEnum Nothing [x] - OutputStream -> GenericOpRep P.OutputStream Nothing [] - ShowAny x -> GenericOpRep P.ShowAny Nothing [x] - ShowScalar x -> GenericOpRep P.ShowScalar Nothing [x] - {-# INLINE fromOp #-} - toOp = \case - GenericOpRep P.Select Nothing [p,x,y] -> Just $ Select p x y - GenericOpRep P.CastOp Nothing [x] -> Just $ CastOp x - GenericOpRep P.BitcastOp Nothing [x] -> Just $ BitcastOp x - GenericOpRep P.UnsafeCoerce Nothing [x] -> Just $ UnsafeCoerce x - GenericOpRep P.GarbageVal Nothing [] -> Just $ GarbageVal - GenericOpRep P.NewRef Nothing [] -> Just $ NewRef - GenericOpRep P.ThrowError Nothing [] -> Just $ ThrowError - GenericOpRep P.SumTag Nothing [x] -> Just $ SumTag x - GenericOpRep P.ToEnum Nothing [x] -> Just $ ToEnum x - GenericOpRep P.OutputStream Nothing [] -> Just $ OutputStream - GenericOpRep P.ShowAny Nothing [x] -> Just $ ShowAny x - GenericOpRep P.ShowScalar Nothing [x] -> Just $ ShowScalar x - _ -> Nothing - {-# INLINE toOp #-} - -instance IRRep r => GenericE (MiscOp r) where - type RepE (MiscOp r) = GenericOpRep (OpConst MiscOp r) r - fromE = fromEGenericOpRep - toE = toEGenericOpRep -instance IRRep r => SinkableE (MiscOp r) -instance IRRep r => HoistableE (MiscOp r) -instance IRRep r => AlphaEqE (MiscOp r) -instance IRRep r => AlphaHashableE (MiscOp r) -instance IRRep r => RenameE (MiscOp r) - instance IRRep r => GenericE (Con r) where type RepE (Con r) = EitherE2 (EitherE4 @@ -1567,12 +1311,8 @@ instance Hashable IxMethod instance Hashable BuiltinClassName instance Hashable Kind -instance IRRep r => Store (MiscOp r n) -instance IRRep r => Store (VectorOp r n) -instance IRRep r => Store (MemOp r n) instance IRRep r => Store (TyCon r n) instance IRRep r => Store (Con r n) -instance IRRep r => Store (PrimOp r n) instance IRRep r => Store (RepVal r n) instance IRRep r => Store (Type r n) instance Store Kind @@ -1605,7 +1345,6 @@ instance Store IxMethod instance IRRep r => Store (Dict r n) instance IRRep r => Store (TypedHof r n) instance IRRep r => Store (Hof r n) -instance IRRep r => Store (RefOp r n) instance Store (NewtypeCon n) instance Store (NewtypeTyCon n) instance Store (DotMethods n) @@ -1683,43 +1422,6 @@ instance IRRep r => PrettyPrec (Con r n) where p :: Pretty a => a -> Doc ann p = pretty -instance IRRep r => Pretty (PrimOp r n) where pretty = prettyFromPrettyPrec -instance IRRep r => PrettyPrec (PrimOp r n) where - prettyPrec = \case - MemOp op -> prettyPrec op - VectorOp op -> prettyPrec op - RefOp ref eff -> atPrec LowestPrec case eff of - MGet -> "get" <+> pApp ref - MPut x -> pApp ref <+> ":=" <+> pApp x - IndexRef i -> pApp ref <+> "!" <+> pApp i - ProjRef i -> "proj_ref" <+> pApp ref <+> p i - UnOp op x -> prettyOpDefault (UUnOp op) [x] - BinOp op x y -> prettyOpDefault (UBinOp op) [x, y] - MiscOp op -> prettyOpGeneric op - where - p :: Pretty a => a -> Doc ann - p = pretty - -instance IRRep r => Pretty (MemOp r n) where pretty = prettyFromPrettyPrec -instance IRRep r => PrettyPrec (MemOp r n) where - prettyPrec = \case - PtrOffset ptr idx -> atPrec LowestPrec $ pApp ptr <+> "+>" <+> pApp idx - PtrLoad ptr -> atPrec AppPrec $ pAppArg "load" [ptr] - op -> prettyOpGeneric op - -instance IRRep r => Pretty (VectorOp r n) where pretty = prettyFromPrettyPrec -instance IRRep r => PrettyPrec (VectorOp r n) where - prettyPrec = \case - VectorBroadcast v -> atPrec LowestPrec $ "vbroadcast" <+> pApp v - VectorIota -> atPrec LowestPrec $ "viota" - VectorIdx tbl i -> atPrec LowestPrec $ "vslice" <+> pApp tbl <+> pApp i - VectorSubref ref i -> atPrec LowestPrec $ "vrefslice" <+> pApp ref <+> pApp i - -prettyOpGeneric :: (IRRep r, GenericOp op, Show (OpConst op r)) => op r n -> DocPrec ann -prettyOpGeneric op = case fromEGenericOpRep op of - GenericOpRep op' Nothing [] -> atPrec ArgPrec (pretty $ show op') - GenericOpRep op' ts xs -> atPrec AppPrec $ pAppArg (pretty (show op')) xs <+> pretty ts - instance Pretty IxMethod where pretty method = pretty $ show method diff --git a/src/lib/Types/OpNames.hs b/src/lib/Types/OpNames.hs deleted file mode 100644 index 85ccc4418..000000000 --- a/src/lib/Types/OpNames.hs +++ /dev/null @@ -1,126 +0,0 @@ --- Copyright 2023 Google LLC --- --- Use of this source code is governed by a BSD-style --- license that can be found in the LICENSE file or at --- https://developers.google.com/open-source/licenses/bsd - --- This module contains payload-free versions of the ops defined in Types.Core. --- It uses the same constructor names so it should be imported qualified. - -module Types.OpNames where - -import IRVariants -import Data.Hashable -import GHC.Generics (Generic (..)) -import Data.Store (Store (..)) - -import PPrint - -data TC = ProdType | SumType | RefType | TypeKind -data Con = ProdCon | SumCon Int - -data BinOp = - IAdd | ISub | IMul | IDiv | ICmp CmpOp | FAdd | FSub | FMul - | FDiv | FCmp CmpOp | FPow | BAnd | BOr | BShL | BShR | IRem | BXor - -data UnOp = - Exp | Exp2 | Log | Log2 | Log10 | Log1p | Sin | Cos | Tan | Sqrt | Floor - | Ceil | Round | LGamma | Erf | Erfc | FNeg | BNot - -data CmpOp = Less | Greater | Equal | LessEqual | GreaterEqual - -data MemOp = IOAlloc | IOFree | PtrOffset | PtrLoad | PtrStore - -data MiscOp = - Select | CastOp | BitcastOp | UnsafeCoerce | GarbageVal | NewRef | Effects - | ThrowError | ThrowException | Tag | SumTag | Create | ToEnum - | OutputStream | ShowAny | ShowScalar - -data VectorOp = VectorBroadcast | VectorIota | VectorIdx | VectorSubref - -data Hof (r::IR) = - While | RunReader | RunWriter | RunState | RunIO | RunInit - | CatchException | Linearize | Transpose - -data DAMOp = Seq | RememberDest | AllocDest | Place | Freeze - -data RefOp = MAsk | MExtend | MGet | MPut | IndexRef | ProjRef Projection - -data Projection = - UnwrapNewtype -- TODO: add `HasCore r` constraint - | ProjectProduct Int - deriving (Show, Eq, Generic) - -data UserEffectOp = Handle | Resume | Perform - -deriving instance Generic BinOp -deriving instance Generic UnOp -deriving instance Generic CmpOp -deriving instance Generic TC -deriving instance Generic Con -deriving instance Generic MemOp -deriving instance Generic MiscOp -deriving instance Generic VectorOp -deriving instance Generic (Hof r) -deriving instance Generic DAMOp -deriving instance Generic RefOp -deriving instance Generic UserEffectOp - -instance Hashable BinOp -instance Hashable UnOp -instance Hashable CmpOp -instance Hashable TC -instance Hashable Con -instance Hashable MemOp -instance Hashable MiscOp -instance Hashable VectorOp -instance Hashable (Hof r) -instance Hashable DAMOp -instance Hashable RefOp -instance Hashable UserEffectOp -instance Hashable Projection - -instance Store BinOp -instance Store UnOp -instance Store CmpOp -instance Store TC -instance Store Con -instance Store MemOp -instance Store MiscOp -instance Store VectorOp -instance IRRep r => Store (Hof r) -instance Store DAMOp -instance Store RefOp -instance Store UserEffectOp -instance Store Projection - -deriving instance Show BinOp -deriving instance Show UnOp -deriving instance Show CmpOp -deriving instance Show TC -deriving instance Show Con -deriving instance Show MemOp -deriving instance Show MiscOp -deriving instance Show VectorOp -deriving instance Show (Hof r) -deriving instance Show DAMOp -deriving instance Show RefOp -deriving instance Show UserEffectOp - -deriving instance Eq BinOp -deriving instance Eq UnOp -deriving instance Eq CmpOp -deriving instance Eq TC -deriving instance Eq Con -deriving instance Eq MemOp -deriving instance Eq MiscOp -deriving instance Eq VectorOp -deriving instance Eq (Hof r) -deriving instance Eq DAMOp -deriving instance Eq RefOp -deriving instance Eq UserEffectOp - -instance Pretty Projection where - pretty = \case - UnwrapNewtype -> "u" - ProjectProduct i -> pretty i diff --git a/src/lib/Types/Primitives.hs b/src/lib/Types/Primitives.hs index d861ab552..f0f8bbf17 100644 --- a/src/lib/Types/Primitives.hs +++ b/src/lib/Types/Primitives.hs @@ -37,8 +37,81 @@ import GHC.Generics (Generic (..)) import PPrint -- import Occurrence -import Types.OpNames (UnOp (..), BinOp (..), CmpOp (..), Projection (..)) import Name +import IRVariants + +-- === Primitive ops === + +data BinOp = + IAdd | ISub | IMul | IDiv | ICmp CmpOp | FAdd | FSub | FMul + | FDiv | FCmp CmpOp | FPow | BAnd | BOr | BShL | BShR | IRem | BXor + deriving (Show, Eq, Ord, Generic) + +data UnOp = + Exp | Exp2 | Log | Log2 | Log10 | Log1p | Sin | Cos | Tan | Sqrt | Floor + | Ceil | Round | LGamma | Erf | Erfc | FNeg | BNot + deriving (Show, Eq, Ord, Generic) + +data CmpOp = Less | Greater | Equal | LessEqual | GreaterEqual + deriving (Show, Eq, Ord, Generic) + +data Projection = + UnwrapNewtype -- TODO: add `HasCore r` constraint + | ProjectProduct Int + deriving (Show, Eq, Ord, Generic) + +data PrimOp (r::IR) (a:: *) = + UnOp UnOp a + | BinOp BinOp a a + | MemOp (MemOp r a) + | VectorOp (VectorOp r a) + | MiscOp (MiscOp r a) + | RefOp a (RefOp r a) + deriving (Show, Eq, Ord, Generic, Functor, Foldable, Traversable) + +data MemOp (r::IR) (a:: *) = + IOAlloc a + | IOFree a + | PtrOffset a a + | PtrLoad a + | PtrStore a a + deriving (Show, Eq, Ord, Generic, Functor, Foldable, Traversable) + +data MiscOp (r::IR) (a:: *) = + Select a a a -- (3) predicate, val-if-true, val-if-false + | CastOp a -- (2) See CheckType.hs for valid coercions. + | BitcastOp a -- (2) See CheckType.hs for valid coercions. + | UnsafeCoerce a -- type, then value. Assumes runtime representation is the same. + | GarbageVal -- (TODO: redundant with NewRef) + | NewRef + | ThrowError + -- Tag of a sum type + | SumTag a + -- Create an enum (payload-free ADT) from a Word8 + | ToEnum a + -- printing + | OutputStream + | ShowAny a -- implemented in Simplify + | ShowScalar a -- Implemented in Imp. Result is a pair of an `IdxRepValTy` + -- giving the logical size of the result and a fixed-size table, + -- `Fin showStringBufferSize => Char`, assumed to have sufficient space. + deriving (Show, Eq, Ord, Generic, Functor, Foldable, Traversable) + +data VectorOp r a = + VectorBroadcast a + | VectorIota + | VectorIdx a a -- table, base ix + | VectorSubref a a -- ref, base ix + deriving (Show, Eq, Ord, Generic, Functor, Foldable, Traversable) + +data RefOp r a = + MGet + | MPut a + | IndexRef a + | ProjRef Projection + deriving (Show, Eq, Ord, Generic, Functor, Foldable, Traversable) + +-- === various things === newtype SourceName = MkSourceName String deriving (Show, Eq, Ord, Generic) @@ -284,5 +357,63 @@ instance PrettyPrec ScalarBaseType where Word32Type -> "Word32" Word64Type -> "Word64" +instance (IRRep r, PrettyPrec a) => Pretty (PrimOp r a) where pretty = prettyFromPrettyPrec +instance (IRRep r, PrettyPrec a) => PrettyPrec (PrimOp r a) where + prettyPrec = \case + MemOp op -> prettyPrec op + VectorOp op -> prettyPrec op + RefOp ref eff -> atPrec LowestPrec case eff of + MGet -> "get" <+> pApp ref + MPut x -> pApp ref <+> ":=" <+> pApp x + IndexRef i -> pApp ref <+> "!" <+> pApp i + ProjRef i -> "proj_ref" <+> pApp ref <+> p i + UnOp op x -> undefined + BinOp op x y -> undefined + MiscOp op -> undefined + where + p :: forall a ann. Pretty a => a -> Doc ann + p = pretty + +instance Pretty Projection where + pretty = \case + UnwrapNewtype -> "u" + ProjectProduct i -> pretty i + +instance (IRRep r, PrettyPrec a) => Pretty (MemOp r a) where pretty = prettyFromPrettyPrec +instance (IRRep r, PrettyPrec a) => PrettyPrec (MemOp r a) where + prettyPrec = \case + PtrOffset ptr idx -> atPrec LowestPrec $ pApp ptr <+> "+>" <+> pApp idx + PtrLoad ptr -> atPrec AppPrec $ pAppArg "load" [ptr] + op -> undefined + +instance (IRRep r, PrettyPrec a) => Pretty (VectorOp r a) where pretty = prettyFromPrettyPrec +instance (IRRep r, PrettyPrec a) => PrettyPrec (VectorOp r a) where + prettyPrec = \case + VectorBroadcast v -> atPrec LowestPrec $ "vbroadcast" <+> pApp v + VectorIota -> atPrec LowestPrec $ "viota" + VectorIdx tbl i -> atPrec LowestPrec $ "vslice" <+> pApp tbl <+> pApp i + VectorSubref ref i -> atPrec LowestPrec $ "vrefslice" <+> pApp ref <+> pApp i + + instance Pretty Explicitness where pretty expl = pretty (show expl) + +instance Hashable BinOp +instance Hashable UnOp +instance Hashable CmpOp +instance Hashable Projection +instance (IRRep r, Hashable a) => Hashable (PrimOp r a) +instance (IRRep r, Hashable a) => Hashable (MemOp r a) +instance (IRRep r, Hashable a) => Hashable (MiscOp r a) +instance (IRRep r, Hashable a) => Hashable (VectorOp r a) +instance (IRRep r, Hashable a) => Hashable (RefOp r a) + +instance Store BinOp +instance Store UnOp +instance Store CmpOp +instance Store Projection +instance (IRRep r, Store a) => Store (PrimOp r a) +instance (IRRep r, Store a) => Store (MemOp r a) +instance (IRRep r, Store a) => Store (MiscOp r a) +instance (IRRep r, Store a) => Store (VectorOp r a) +instance (IRRep r, Store a) => Store (RefOp r a) diff --git a/src/lib/Types/Source.hs b/src/lib/Types/Source.hs index d1e0ce755..3d435a12f 100644 --- a/src/lib/Types/Source.hs +++ b/src/lib/Types/Source.hs @@ -38,7 +38,6 @@ import Data.String (fromString) import Err import PPrint import Name -import qualified Types.OpNames as P import IRVariants import MonadUtil import Util (File (..), SnocList) @@ -632,11 +631,11 @@ data EnvQuery = data PrimName = UBaseType BaseType - | UPrimTC P.TC - | UCon P.Con - | UMemOp P.MemOp - | UVectorOp P.VectorOp - | UMiscOp P.MiscOp + | UPrimTC TCName + | UCon ConName + | UMemOp MemOpName + | UVectorOp VectorOpName + | UMiscOp MiscOpName | UUnOp UnOp | UBinOp BinOp | UMGet | UMPut @@ -647,6 +646,13 @@ data PrimName = | UTuple -- overloaded for type constructor and data constructor, resolved in inference deriving (Show, Eq, Generic) +data TCName = ProdType | SumType | RefType | TypeKind deriving (Show, Eq, Generic) +data ConName = ProdCon | SumCon Int deriving (Show, Eq, Generic) + +type MemOpName = MemOp CoreIR () +type VectorOpName = VectorOp CoreIR () +type MiscOpName = MiscOp CoreIR () + -- === primitive constructors and operators === strToPrimName :: String -> Maybe PrimName @@ -686,7 +692,7 @@ primNames = M.fromList , ("floor", unary Floor), ("ceil" , unary Ceil), ("round", unary Round) , ("log1p", unary Log1p), ("lgamma", unary LGamma) , ("erf" , unary Erf), ("erfc" , unary Erfc) - , ("TyKind" , UPrimTC $ P.TypeKind) + , ("TyKind" , UPrimTC $ TypeKind) , ("Float64" , baseTy $ Scalar Float64Type) , ("Float32" , baseTy $ Scalar Float32Type) , ("Int64" , baseTy $ Scalar Int64Type) @@ -703,24 +709,24 @@ primNames = M.fromList , ("Nat" , UNat) , ("Fin" , UFin) , ("NatCon" , UNatCon) - , ("Ref" , UPrimTC $ P.RefType) + , ("Ref" , UPrimTC $ RefType) , ("indexRef" , UIndexRef) - , ("alloc" , memOp $ P.IOAlloc) - , ("free" , memOp $ P.IOFree) - , ("ptrOffset", memOp $ P.PtrOffset) - , ("ptrLoad" , memOp $ P.PtrLoad) - , ("ptrStore" , memOp $ P.PtrStore) - , ("throwError" , miscOp $ P.ThrowError) - , ("dataConTag" , miscOp $ P.SumTag) - , ("toEnum" , miscOp $ P.ToEnum) - , ("outputStream" , miscOp $ P.OutputStream) - , ("cast" , miscOp $ P.CastOp) - , ("bitcast" , miscOp $ P.BitcastOp) - , ("unsafeCoerce" , miscOp $ P.UnsafeCoerce) - , ("garbageVal" , miscOp $ P.GarbageVal) - , ("select" , miscOp $ P.Select) - , ("showAny" , miscOp $ P.ShowAny) - , ("showScalar" , miscOp $ P.ShowScalar) + , ("alloc" , memOp $ IOAlloc ()) + , ("free" , memOp $ IOFree ()) + , ("ptrOffset", memOp $ PtrOffset () ()) + , ("ptrLoad" , memOp $ PtrLoad ()) + , ("ptrStore" , memOp $ PtrStore () ()) + , ("throwError" , miscOp $ ThrowError) + , ("dataConTag" , miscOp $ SumTag ()) + , ("toEnum" , miscOp $ ToEnum ()) + , ("outputStream" , miscOp $ OutputStream) + , ("cast" , miscOp $ CastOp ()) + , ("bitcast" , miscOp $ BitcastOp ()) + , ("unsafeCoerce" , miscOp $ UnsafeCoerce ()) + , ("garbageVal" , miscOp $ GarbageVal) + , ("select" , miscOp $ Select () () ()) + , ("showAny" , miscOp $ ShowAny ()) + , ("showScalar" , miscOp $ ShowScalar ()) , ("projNewtype" , UProjNewtype) , ("applyMethod0" , UApplyMethod 0) , ("applyMethod1" , UApplyMethod 1)