Admin message

Due to a large amount of spam we do not allow new users to create repositories, they are "external" users. If you are a new user and want to create a repository, for example for forking GHC, open a new issue on ghc/ghc using the "get-verified" issue template

PrimOpIds and PrimOpWrappers
I discussed with @bgamari two related issues 1. **Use the primop wrappers, instead of always eta-expanding.** The strange module `GHC.PrimopWrappers` is generated by `utils/genprimopcode` from `primops.txt.pp`. It contains bindings like ``` (+#) :: Int# -> Int# -> Int# (+#) x y = (+#) x y ``` This defines a curried function `GHC.PrimopWrappers.(+#)`, whose implementation is an unboxed machine add. The code generator spots that saturated `(+#) x y` in the right hand side, and generates a machine add. Why do we need these curried functions? So that in a higher order call like `f (+#)`, we can pass `GHC.PrimopWrappers.(+#)`. An alternative, is to eta-expand, so that we have `f (\x y. (+#) x y)`; now we don't need that wrapper. We *must* eta-expand for levity-polymorphic primops, because we can't compile levity-polymorphic code in `GHC.PrimopWrappers`. The `hasNoBinding` predicate is true for functions that have no binding -- and that must include levity-polymorphic primops. In !6197 I tried making `hasNoBinding` return False for all non-levity-polymorphic primops. But that caused ``` ghci> data A <interactive>: internal error: stg_ap_v_ret ``` This error comes from somewhere near this code in GHC.UI.Monad ``` runDecls' :: GhciMonad m => [LHsDecl GhcPs] -> m (Maybe [GHC.Name]) runDecls' decls = do st <- getGHCiState liftIO (print "hello2") reifyGHCi $ \x -> withProgName (progname st) $ withArgs (args st) $ reflectGHCi x $ GHC.handleSourceError (\e -> do GHC.printException e; return Nothing) (Just <$> GHC.runParsedDecls decls) ``` If you comment out *both* the `withProgName` and `withArgs` calls, it works; if not, you crash. I'm not sure why; @bgamari may try to find out. 2. **De-duplicate primop wrappers**. GHC currently builds two *different* Ids for PrimOps. In GHC.Types.Id.Make: ``` mkPrimOpId :: PrimOp -> Id mkPrimOpId prim_op ``` In GHC.Builtin.PrimOps: ``` primOpWrapperId :: PrimOp -> Id primOpWrapperId op = mkVanillaGlobalWithInfo name ty info ``` We put both into the symbol table. We also currently generate (using `genprimopcode`) *two* modules: * `GHC.Prim.hs` which contains accurate type signatures and Haddock docs; all RHS are bottom. Also `data Char#` etc (no RHS) for primitive types. This module is used only for Haddock to generate docs. * `GHC.Primopwrappers.hs` which contains no Haddock, just wrappers. Used for unsaturated applications. There seems no reason for all this duplication. Instead: * Kill off `GHC.PrimopWrappers.hs`; instead generate **one** file, but with module name `GHC.Prim`, with accurate types, Haddock, and (for rep-mono primops) wrappers. * This module is generated by `genprimopcode` from `primops.txt.pp`. * It contains Haddock docs for the primops; this documentation comes form `primops.txt.pp` * Even representation-polymorphic primops (for which a wrapper makes no sense) get a defn in `GHC.Prim`, solely to carry the Haddock documentation. * Primitive types get `data Char#` with Haddock docs in `GHC.Prim`. * Pseudo-ops like `nullAddr#` have a type and Haddock, but a dummy (bottom) RHS. They get compulsory unfoldings, so we will never call them. * Kill off `primOpWrapperId`; use `primOpId` instead. (Kill `mkPrimOpWrapperUnique` too.) Ben is going to look into this. Slightly fiddly, but makes things simpler; and the symbol table will be smaller. NB: three kinds of things are defined in `primops.txt.pp`: * Primitive types. `genprimopcode` ignores them. * Primops. `genprimopcode` generates a wrapper function. * Pseudo-ops. `genprimopcode` .... Things to watch out for: #18079, #19982
issue