ghc-lib 0.20201101 → 0.20201201
raw patch · 126 files changed
+7158/−6067 lines, 126 filesdep +parsecdep ~ghc-lib-parserPVP ok
version bump matches the API change (PVP)
Dependencies added: parsec
Dependency ranges changed: ghc-lib-parser
API changes (from Hackage documentation)
- GHC: [cachedPlugins] :: DynFlags -> [LoadedPlugin]
- GHC: [canGenerateDynamicToo] :: DynFlags -> IORef Bool
- GHC: [dynHiSuf] :: DynFlags -> String
- GHC: [dynObjectSuf] :: DynFlags -> String
- GHC: [dynOutputFile] :: DynFlags -> Maybe String
- GHC: [hiSuf] :: DynFlags -> String
- GHC: [objectSuf] :: DynFlags -> String
- GHC: [outputFile] :: DynFlags -> Maybe String
- GHC: [staticPlugins] :: DynFlags -> [StaticPlugin]
- GHC: [ways] :: DynFlags -> Ways
- GHC: splitForAllTys :: Type -> ([TyCoVar], Type)
- GHC.CmmToAsm.Dwarf.Constants: dW_AT_MIPS_linkage_name :: Word
- GHC.CmmToAsm.Monad: [natm_this_module] :: NatM_State -> Module
- GHC.CmmToAsm.PIC: getThisModule :: CmmMakeDynamicReferenceM m => m Module
- GHC.Driver.Main: [hscs_iface_dflags] :: HscStatus -> !DynFlags
- GHC.Driver.Pipeline: exeFileName :: Bool -> DynFlags -> FilePath
- GHC.Driver.Pipeline: linkBinary :: DynFlags -> [FilePath] -> [UnitId] -> IO ()
- GHC.Driver.Pipeline: maybeCreateManifest :: DynFlags -> FilePath -> IO [FilePath]
- GHC.Iface.Ext.Ast: instance (GHC.Iface.Ext.Ast.HasLoc thing, GHC.Iface.Ext.Ast.ToHie (GHC.Iface.Ext.Ast.TScoped thing)) => GHC.Iface.Ext.Ast.ToHie (GHC.Iface.Ext.Ast.TScoped (GHC.Hs.Type.HsImplicitBndrs GHC.Hs.Extension.GhcRn thing))
- GHC.Iface.Ext.Ast: instance (GHC.Iface.Ext.Ast.HasLoc thing, GHC.Iface.Ext.Ast.ToHie (GHC.Iface.Ext.Ast.TScoped thing)) => GHC.Iface.Ext.Ast.ToHie (GHC.Iface.Ext.Ast.TScoped (GHC.Hs.Type.HsWildCardBndrs GHC.Hs.Extension.GhcRn thing))
- GHC.Iface.Ext.Ast: instance GHC.Iface.Ext.Ast.HasLoc (GHC.Hs.Type.LHsQTyVars GHC.Hs.Extension.GhcRn)
- GHC.Iface.Ext.Ast: instance GHC.Iface.Ext.Ast.HasLoc thing => GHC.Iface.Ext.Ast.HasLoc (GHC.Hs.Type.HsImplicitBndrs a thing)
- GHC.Iface.Ext.Ast: instance GHC.Iface.Ext.Ast.HasLoc thing => GHC.Iface.Ext.Ast.HasLoc (GHC.Hs.Type.HsWildCardBndrs a thing)
- GHC.Iface.Ext.Ast: instance GHC.Iface.Ext.Ast.HasLoc thing => GHC.Iface.Ext.Ast.HasLoc (GHC.Iface.Ext.Ast.TScoped thing)
- GHC.Iface.Ext.Ast: instance GHC.Iface.Ext.Ast.ToHie (GHC.Iface.Ext.Ast.TScoped (GHC.Types.SrcLoc.Located (GHC.Hs.Type.HsType GHC.Hs.Extension.GhcRn)))
- GHC.Plugins: splitForAllTy :: Type -> (TyCoVar, Type)
- GHC.Plugins: splitForAllTy_co_maybe :: Type -> Maybe (TyCoVar, Type)
- GHC.Plugins: splitForAllTy_maybe :: Type -> Maybe (TyCoVar, Type)
- GHC.Plugins: splitForAllTy_ty_maybe :: Type -> Maybe (TyCoVar, Type)
- GHC.Plugins: splitForAllTys :: Type -> ([TyCoVar], Type)
- GHC.Plugins: splitForAllTysInvis :: Type -> ([InvisTVBinder], Type)
- GHC.Plugins: splitForAllTysReq :: Type -> ([ReqTVBinder], Type)
- GHC.Plugins: splitForAllVarBndrs :: Type -> ([TyCoVarBinder], Type)
- GHC.Plugins: splitPiTysInvisible :: Type -> ([TyCoBinder], Type)
- GHC.Plugins: splitPiTysInvisibleN :: Int -> Type -> ([TyCoBinder], Type)
- GHC.Rename.HsType: BindUnlessForall :: HsSigWcTypeScoping
- GHC.Rename.HsType: data HsSigWcTypeScoping
- GHC.Rename.HsType: extractHsTvBndrs :: [LHsTyVarBndr flag GhcPs] -> FreeKiTyVars -> FreeKiTyVars
- GHC.Rename.HsType: forAllOrNothing :: Bool -> FreeKiTyVars -> RnM FreeKiTyVars
- GHC.Runtime.Linker: deleteFromLinkEnv :: DynLinker -> [Name] -> IO ()
- GHC.Runtime.Linker: extendLinkEnv :: DynLinker -> [(Name, ForeignHValue)] -> IO ()
- GHC.Runtime.Linker: extendLoadedPkgs :: DynLinker -> [UnitId] -> IO ()
- GHC.Runtime.Linker: getHValue :: HscEnv -> Name -> IO ForeignHValue
- GHC.Runtime.Linker: initDynLinker :: HscEnv -> IO ()
- GHC.Runtime.Linker: instance GHC.Utils.Outputable.Outputable GHC.Runtime.Linker.LibrarySpec
- GHC.Runtime.Linker: linkCmdLineLibs :: HscEnv -> IO ()
- GHC.Runtime.Linker: linkDecls :: HscEnv -> SrcSpan -> CompiledByteCode -> IO ()
- GHC.Runtime.Linker: linkExpr :: HscEnv -> SrcSpan -> UnlinkedBCO -> IO ForeignHValue
- GHC.Runtime.Linker: linkModule :: HscEnv -> Module -> IO ()
- GHC.Runtime.Linker: linkPackages :: HscEnv -> [UnitId] -> IO ()
- GHC.Runtime.Linker: showLinkerState :: DynLinker -> IO SDoc
- GHC.Runtime.Linker: uninitializedLinker :: IO DynLinker
- GHC.Runtime.Linker: unload :: HscEnv -> [Linkable] -> IO ()
- GHC.Runtime.Linker: withExtendedLinkEnv :: ExceptionMonad m => DynLinker -> [(Name, ForeignHValue)] -> m a -> m a
- GHC.SysTools: getFrameworkOpts :: DynFlags -> Platform -> [String]
- GHC.SysTools: getUnitFrameworkOpts :: DynFlags -> Platform -> [UnitId] -> IO [String]
- GHC.SysTools: libmLinkOpts :: [Option]
- GHC.SysTools: linkDynLib :: DynFlags -> [String] -> [UnitId] -> IO ()
- GHC.SysTools.ExtraObj: checkLinkInfo :: DynFlags -> [UnitId] -> FilePath -> IO Bool
- GHC.SysTools.ExtraObj: getCompilerInfo :: DynFlags -> IO CompilerInfo
- GHC.SysTools.ExtraObj: getLinkInfo :: DynFlags -> [UnitId] -> IO String
- GHC.SysTools.ExtraObj: ghcLinkInfoNoteName :: String
- GHC.SysTools.ExtraObj: ghcLinkInfoSectionName :: String
- GHC.SysTools.ExtraObj: haveRtsOptsFlags :: DynFlags -> Bool
- GHC.SysTools.ExtraObj: mkExtraObj :: DynFlags -> Suffix -> String -> IO FilePath
- GHC.SysTools.ExtraObj: mkExtraObjToLinkIntoBinary :: DynFlags -> IO FilePath
- GHC.SysTools.ExtraObj: mkNoteObjsToLinkIntoBinary :: DynFlags -> [UnitId] -> IO [FilePath]
- GHC.SysTools.ExtraObj: platformSupportsSavingLinkOpts :: OS -> Bool
- GHC.SysTools.Tasks: runInjectRPaths :: DynFlags -> [FilePath] -> FilePath -> IO ()
- GHC.Tc.Gen.HsType: tcNamedWildCardBinders :: [Name] -> ([(Name, TcTyVar)] -> TcM a) -> TcM a
- GHC.Tc.Solver: emitFlatConstraints :: WantedConstraints -> TcM ()
- GHC.Tc.Utils.Monad: withDoDynamicToo :: TcRnIf gbl lcl a -> TcRnIf gbl lcl a
+ GHC: Opt_ExposeInternalSymbols :: GeneralFlag
+ GHC: [callerCcFilters] :: DynFlags -> [CallerCcFilter]
+ GHC: [dynHiSuf_] :: DynFlags -> String
+ GHC: [dynObjectSuf_] :: DynFlags -> String
+ GHC: [dynOutputFile_] :: DynFlags -> Maybe String
+ GHC: [dynamicNow] :: DynFlags -> !Bool
+ GHC: [dynamicTooFailed] :: DynFlags -> IORef Bool
+ GHC: [hiSuf_] :: DynFlags -> String
+ GHC: [objectSuf_] :: DynFlags -> String
+ GHC: [outputFile_] :: DynFlags -> Maybe String
+ GHC: [targetWays_] :: DynFlags -> Ways
+ GHC: splitForAllTyCoVars :: Type -> ([TyCoVar], Type)
+ GHC.CmmToAsm.Dwarf.Constants: dW_AT_linkage_name :: Word
+ GHC.CmmToAsm.Monad: instance GHC.Unit.Module.HasModule GHC.CmmToAsm.Monad.NatM
+ GHC.HsToCore.Docs: sigTypeDocs :: HsSigType GhcRn -> Map Int HsDocString
+ GHC.Iface.Ext.Ast: instance Data.Data.Data flag => GHC.Iface.Ext.Ast.ToHie (GHC.Iface.Ext.Ast.TVScoped (GHC.Hs.Type.HsOuterTyVarBndrs flag GHC.Hs.Extension.GhcRn))
+ GHC.Iface.Ext.Ast: instance GHC.Iface.Ext.Ast.ToHie (GHC.Iface.Ext.Ast.TScoped (GHC.Hs.Type.HsWildCardBndrs GHC.Hs.Extension.GhcRn (GHC.Types.SrcLoc.Located (GHC.Hs.Type.HsSigType GHC.Hs.Extension.GhcRn))))
+ GHC.Iface.Ext.Ast: instance GHC.Iface.Ext.Ast.ToHie (GHC.Iface.Ext.Ast.TScoped (GHC.Hs.Type.HsWildCardBndrs GHC.Hs.Extension.GhcRn (GHC.Types.SrcLoc.Located (GHC.Hs.Type.HsType GHC.Hs.Extension.GhcRn))))
+ GHC.Iface.Ext.Ast: instance GHC.Iface.Ext.Ast.ToHie (GHC.Iface.Ext.Ast.TScoped (GHC.Types.SrcLoc.Located (GHC.Hs.Type.HsSigType GHC.Hs.Extension.GhcRn)))
+ GHC.Linker.Dynamic: libmLinkOpts :: [Option]
+ GHC.Linker.Dynamic: linkDynLib :: DynFlags -> [String] -> [UnitId] -> IO ()
+ GHC.Linker.ExtraObj: checkLinkInfo :: DynFlags -> [UnitId] -> FilePath -> IO Bool
+ GHC.Linker.ExtraObj: getCompilerInfo :: DynFlags -> IO CompilerInfo
+ GHC.Linker.ExtraObj: getLinkInfo :: DynFlags -> [UnitId] -> IO String
+ GHC.Linker.ExtraObj: ghcLinkInfoNoteName :: String
+ GHC.Linker.ExtraObj: ghcLinkInfoSectionName :: String
+ GHC.Linker.ExtraObj: haveRtsOptsFlags :: DynFlags -> Bool
+ GHC.Linker.ExtraObj: mkExtraObj :: DynFlags -> Suffix -> String -> IO FilePath
+ GHC.Linker.ExtraObj: mkExtraObjToLinkIntoBinary :: DynFlags -> IO FilePath
+ GHC.Linker.ExtraObj: mkNoteObjsToLinkIntoBinary :: DynFlags -> [UnitId] -> IO [FilePath]
+ GHC.Linker.ExtraObj: platformSupportsSavingLinkOpts :: OS -> Bool
+ GHC.Linker.Loader: Loader :: MVar (Maybe LoaderState) -> Loader
+ GHC.Linker.Loader: LoaderState :: ClosureEnv -> !ItblEnv -> ![Linkable] -> ![Linkable] -> ![UnitId] -> ![(FilePath, String)] -> LoaderState
+ GHC.Linker.Loader: [bcos_loaded] :: LoaderState -> ![Linkable]
+ GHC.Linker.Loader: [closure_env] :: LoaderState -> ClosureEnv
+ GHC.Linker.Loader: [itbl_env] :: LoaderState -> !ItblEnv
+ GHC.Linker.Loader: [loader_state] :: Loader -> MVar (Maybe LoaderState)
+ GHC.Linker.Loader: [objs_loaded] :: LoaderState -> ![Linkable]
+ GHC.Linker.Loader: [pkgs_loaded] :: LoaderState -> ![UnitId]
+ GHC.Linker.Loader: [temp_sos] :: LoaderState -> ![(FilePath, String)]
+ GHC.Linker.Loader: data LoaderState
+ GHC.Linker.Loader: deleteFromLoadedEnv :: Loader -> [Name] -> IO ()
+ GHC.Linker.Loader: extendLoadedEnv :: Loader -> [(Name, ForeignHValue)] -> IO ()
+ GHC.Linker.Loader: extendLoadedPkgs :: Loader -> [UnitId] -> IO ()
+ GHC.Linker.Loader: initLoaderState :: HscEnv -> IO ()
+ GHC.Linker.Loader: instance GHC.Utils.Outputable.Outputable GHC.Linker.Loader.LibrarySpec
+ GHC.Linker.Loader: loadCmdLineLibs :: HscEnv -> IO ()
+ GHC.Linker.Loader: loadDecls :: HscEnv -> SrcSpan -> CompiledByteCode -> IO ()
+ GHC.Linker.Loader: loadExpr :: HscEnv -> SrcSpan -> UnlinkedBCO -> IO ForeignHValue
+ GHC.Linker.Loader: loadModule :: HscEnv -> Module -> IO ()
+ GHC.Linker.Loader: loadName :: HscEnv -> Name -> IO ForeignHValue
+ GHC.Linker.Loader: loadPackages :: HscEnv -> [UnitId] -> IO ()
+ GHC.Linker.Loader: newtype Loader
+ GHC.Linker.Loader: showLoaderState :: Loader -> IO SDoc
+ GHC.Linker.Loader: uninitializedLoader :: IO Loader
+ GHC.Linker.Loader: unload :: HscEnv -> [Linkable] -> IO ()
+ GHC.Linker.Loader: withExtendedLoadedEnv :: ExceptionMonad m => Loader -> [(Name, ForeignHValue)] -> m a -> m a
+ GHC.Linker.MacOS: getFrameworkOpts :: DynFlags -> Platform -> [String]
+ GHC.Linker.MacOS: getUnitFrameworkOpts :: DynFlags -> Platform -> [UnitId] -> IO [String]
+ GHC.Linker.MacOS: getUnitFrameworkPath :: SDocContext -> UnitState -> HomeUnit -> [UnitId] -> IO [String]
+ GHC.Linker.MacOS: getUnitFrameworks :: SDocContext -> UnitState -> HomeUnit -> [UnitId] -> IO [String]
+ GHC.Linker.MacOS: loadFramework :: HscEnv -> [FilePath] -> FilePath -> IO (Maybe String)
+ GHC.Linker.MacOS: runInjectRPaths :: DynFlags -> [FilePath] -> FilePath -> IO ()
+ GHC.Linker.Static: exeFileName :: Platform -> Bool -> Maybe FilePath -> FilePath
+ GHC.Linker.Static: linkBinary :: DynFlags -> [FilePath] -> [UnitId] -> IO ()
+ GHC.Linker.Static: linkBinary' :: Bool -> DynFlags -> [FilePath] -> [UnitId] -> IO ()
+ GHC.Linker.Static: linkStaticLib :: DynFlags -> [String] -> [UnitId] -> IO ()
+ GHC.Linker.Unit: collectArchives :: DynFlags -> UnitInfo -> IO [FilePath]
+ GHC.Linker.Unit: collectLibraryPaths :: Ways -> [UnitInfo] -> [FilePath]
+ GHC.Linker.Unit: collectLinkOpts :: DynFlags -> [UnitInfo] -> ([String], [String], [String])
+ GHC.Linker.Unit: getLibs :: DynFlags -> [UnitId] -> IO [(String, String)]
+ GHC.Linker.Unit: getUnitLibraryPath :: SDocContext -> UnitState -> HomeUnit -> Ways -> [UnitId] -> IO [String]
+ GHC.Linker.Unit: getUnitLinkOpts :: DynFlags -> [UnitId] -> IO ([String], [String], [String])
+ GHC.Linker.Unit: packageHsLibs :: DynFlags -> UnitInfo -> [String]
+ GHC.Linker.Windows: maybeCreateManifest :: DynFlags -> FilePath -> IO [FilePath]
+ GHC.Plugins: splitForAllCoVar_maybe :: Type -> Maybe (TyCoVar, Type)
+ GHC.Plugins: splitForAllInvisTVBinders :: Type -> ([InvisTVBinder], Type)
+ GHC.Plugins: splitForAllReqTVBinders :: Type -> ([ReqTVBinder], Type)
+ GHC.Plugins: splitForAllTyCoVar :: Type -> (TyCoVar, Type)
+ GHC.Plugins: splitForAllTyCoVarBinders :: Type -> ([TyCoVarBinder], Type)
+ GHC.Plugins: splitForAllTyCoVar_maybe :: Type -> Maybe (TyCoVar, Type)
+ GHC.Plugins: splitForAllTyCoVars :: Type -> ([TyCoVar], Type)
+ GHC.Plugins: splitForAllTyVar_maybe :: Type -> Maybe (TyCoVar, Type)
+ GHC.Plugins: splitInvisPiTys :: Type -> ([TyCoBinder], Type)
+ GHC.Plugins: splitInvisPiTysN :: Int -> Type -> ([TyCoBinder], Type)
+ GHC.Rename.HsType: bindHsOuterTyVarBndrs :: OutputableBndrFlag flag => HsDocContext -> Maybe assoc -> FreeKiTyVars -> HsOuterTyVarBndrs flag GhcPs -> (HsOuterTyVarBndrs flag GhcRn -> RnM (a, FreeVars)) -> RnM (a, FreeVars)
+ GHC.Rename.HsType: data HsPatSigTypeScoping
+ GHC.Rename.HsType: extractHsOuterTvBndrs :: HsOuterTyVarBndrs flag GhcPs -> FreeKiTyVars -> FreeKiTyVars
+ GHC.Tc.Gen.HsType: bindNamedWildCardBinders :: [Name] -> ([(Name, TcTyVar)] -> TcM a) -> TcM a
+ GHC.Tc.Gen.HsType: bindOuterFamEqnTKBndrs :: HsOuterFamEqnTyVarBndrs GhcRn -> TcM a -> TcM ([TcTyVar], a)
+ GHC.Tc.Gen.HsType: bindOuterFamEqnTKBndrs_Q_Tv :: HsOuterFamEqnTyVarBndrs GhcRn -> TcM a -> TcM ([TcTyVar], a)
+ GHC.Tc.Gen.HsType: bindOuterSigTKBndrs_Tv :: HsOuterSigTyVarBndrs GhcRn -> TcM a -> TcM (HsOuterSigTyVarBndrs GhcTc, a)
+ GHC.Tc.Gen.HsType: scopedSortOuter :: HsOuterTyVarBndrs Specificity GhcTc -> TcM [InvisTVBinder]
+ GHC.Tc.Gen.HsType: tcExplicitTKBndrs :: OutputableBndrFlag flag => [LHsTyVarBndr flag GhcRn] -> TcM a -> TcM ([VarBndr TyVar flag], a)
+ GHC.Tc.Gen.HsType: tcOuterTKBndrs :: OutputableBndrFlag flag => SkolemInfo -> HsOuterTyVarBndrs flag GhcRn -> TcM a -> TcM (HsOuterTyVarBndrs flag GhcTc, a)
+ GHC.Tc.Solver: simplifyAndEmitFlatConstraints :: WantedConstraints -> TcM ()
+ GHC.Tc.Utils.Monad: withDynamicNow :: TcRnIf gbl lcl a -> TcRnIf gbl lcl a
+ GHC.Tc.Utils.Monad: withoutDynamicNow :: TcRnIf gbl lcl a -> TcRnIf gbl lcl a
- GHC: DynFlags :: GhcMode -> GhcLink -> !Backend -> {-# UNPACK #-} !GhcNameVersion -> {-# UNPACK #-} !FileSettings -> Platform -> {-# UNPACK #-} !ToolSettings -> {-# UNPACK #-} !PlatformMisc -> [(String, String)] -> LlvmConfig -> Int -> Int -> Int -> Int -> Int -> Maybe String -> Maybe String -> [Int] -> Maybe Int -> Bool -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Int -> Int -> Int -> Maybe Int -> Maybe Int -> Int -> Word -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Bool -> Maybe Int -> Int -> [FilePath] -> ModuleName -> Maybe String -> IntWithInf -> IntWithInf -> UnitId -> Maybe UnitId -> [(ModuleName, Module)] -> Ways -> Maybe (String, Int) -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> String -> String -> String -> String -> IORef Bool -> String -> String -> Maybe String -> Maybe String -> Maybe String -> DynLibLoader -> Maybe FilePath -> Maybe FilePath -> [Option] -> IncludeSpecs -> [String] -> [String] -> [String] -> Maybe String -> RtsOptsEnabled -> Bool -> String -> [ModuleName] -> [(ModuleName, String)] -> [String] -> [LoadedPlugin] -> [StaticPlugin] -> Hooks -> FilePath -> Bool -> Bool -> [ModuleName] -> [String] -> [PackageDBFlag] -> [IgnorePackageFlag] -> [PackageFlag] -> [PackageFlag] -> [TrustFlag] -> Maybe FilePath -> Maybe [UnitDatabase UnitId] -> UnitState -> IORef FilesToClean -> IORef (Map FilePath FilePath) -> IORef Int -> IORef (Set FilePath) -> EnumSet DumpFlag -> EnumSet GeneralFlag -> EnumSet WarningFlag -> EnumSet WarningFlag -> Maybe Language -> SafeHaskellMode -> Bool -> Bool -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> [OnOff Extension] -> EnumSet Extension -> !UnfoldingOpts -> Int -> Int -> LogAction -> DumpAction -> TraceAction -> FlushOut -> FlushErr -> Maybe FilePath -> Maybe String -> [String] -> Int -> Int -> Bool -> OverridingBool -> Bool -> Scheme -> ProfAuto -> Maybe String -> IORef (ModuleEnv Int) -> Maybe SseVersion -> Maybe BmiVersion -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> IORef (Maybe LinkerInfo) -> IORef (Maybe CompilerInfo) -> Int -> Int -> Int -> Bool -> Maybe Int -> Int -> Int -> Weights -> DynFlags
+ GHC: DynFlags :: GhcMode -> GhcLink -> !Backend -> {-# UNPACK #-} !GhcNameVersion -> {-# UNPACK #-} !FileSettings -> Platform -> {-# UNPACK #-} !ToolSettings -> {-# UNPACK #-} !PlatformMisc -> [(String, String)] -> LlvmConfig -> Int -> Int -> Int -> Int -> Int -> Maybe String -> Maybe String -> [Int] -> Maybe Int -> Bool -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Int -> Int -> Int -> Maybe Int -> Maybe Int -> Int -> Word -> Maybe Int -> Maybe Int -> Maybe Int -> Maybe Int -> Bool -> Maybe Int -> Int -> [FilePath] -> ModuleName -> Maybe String -> IntWithInf -> IntWithInf -> UnitId -> Maybe UnitId -> [(ModuleName, Module)] -> Ways -> Maybe (String, Int) -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> String -> String -> String -> String -> IORef Bool -> String -> String -> Maybe String -> Maybe String -> Maybe String -> DynLibLoader -> !Bool -> Maybe FilePath -> Maybe FilePath -> [Option] -> IncludeSpecs -> [String] -> [String] -> [String] -> Maybe String -> RtsOptsEnabled -> Bool -> String -> [ModuleName] -> [(ModuleName, String)] -> [String] -> Hooks -> FilePath -> Bool -> Bool -> [ModuleName] -> [String] -> [PackageDBFlag] -> [IgnorePackageFlag] -> [PackageFlag] -> [PackageFlag] -> [TrustFlag] -> Maybe FilePath -> Maybe [UnitDatabase UnitId] -> UnitState -> IORef FilesToClean -> IORef (Map FilePath FilePath) -> IORef Int -> IORef (Set FilePath) -> EnumSet DumpFlag -> EnumSet GeneralFlag -> EnumSet WarningFlag -> EnumSet WarningFlag -> Maybe Language -> SafeHaskellMode -> Bool -> Bool -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> SrcSpan -> [OnOff Extension] -> EnumSet Extension -> !UnfoldingOpts -> Int -> Int -> LogAction -> DumpAction -> TraceAction -> FlushOut -> FlushErr -> Maybe FilePath -> Maybe String -> [String] -> Int -> Int -> Bool -> OverridingBool -> Bool -> Scheme -> ProfAuto -> [CallerCcFilter] -> Maybe String -> IORef (ModuleEnv Int) -> Maybe SseVersion -> Maybe BmiVersion -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> IORef (Maybe LinkerInfo) -> IORef (Maybe CompilerInfo) -> Int -> Int -> Int -> Bool -> Maybe Int -> Int -> Int -> Weights -> DynFlags
- GHC.CmmToAsm: cmmNativeGen :: forall statics instr jumpDest. (Instruction instr, OutputableP Platform statics, Outputable jumpDest) => DynFlags -> Module -> ModLocation -> NcgImpl statics instr jumpDest -> UniqSupply -> DwarfFiles -> LabelMap DebugBlock -> RawCmmDecl -> Int -> IO (UniqSupply, DwarfFiles, [NatCmmDecl statics instr], [CLabel], Maybe [RegAllocStats statics instr], Maybe [RegAllocStats], LabelMap [UnwindPoint])
+ GHC.CmmToAsm: cmmNativeGen :: forall statics instr jumpDest. (Instruction instr, OutputableP Platform statics, Outputable jumpDest) => DynFlags -> ModLocation -> NcgImpl statics instr jumpDest -> UniqSupply -> DwarfFiles -> LabelMap DebugBlock -> RawCmmDecl -> Int -> IO (UniqSupply, DwarfFiles, [NatCmmDecl statics instr], [CLabel], Maybe [RegAllocStats statics instr], Maybe [RegAllocStats], LabelMap [UnwindPoint])
- GHC.CmmToAsm: initNCGConfig :: DynFlags -> NCGConfig
+ GHC.CmmToAsm: initNCGConfig :: DynFlags -> Module -> NCGConfig
- GHC.CmmToAsm.Monad: NatM_State :: UniqSupply -> Int -> [CLabel] -> Maybe Reg -> NCGConfig -> Module -> ModLocation -> DwarfFiles -> LabelMap DebugBlock -> CFG -> NatM_State
+ GHC.CmmToAsm.Monad: NatM_State :: UniqSupply -> Int -> [CLabel] -> Maybe Reg -> NCGConfig -> ModLocation -> DwarfFiles -> LabelMap DebugBlock -> CFG -> NatM_State
- GHC.CmmToAsm.Monad: mkNatM_State :: UniqSupply -> Int -> NCGConfig -> Module -> ModLocation -> DwarfFiles -> LabelMap DebugBlock -> CFG -> NatM_State
+ GHC.CmmToAsm.Monad: mkNatM_State :: UniqSupply -> Int -> NCGConfig -> ModLocation -> DwarfFiles -> LabelMap DebugBlock -> CFG -> NatM_State
- GHC.CmmToAsm.Reg.Graph.Stats: RegAllocStatsSpill :: [LiveCmmDecl statics instr] -> Graph VirtualReg RegClass RealReg -> UniqFM VirtualReg VirtualReg -> SpillStats -> SpillCostInfo -> [LiveCmmDecl statics instr] -> RegAllocStats statics instr
+ GHC.CmmToAsm.Reg.Graph.Stats: RegAllocStatsSpill :: [LiveCmmDecl statics instr] -> Graph VirtualReg RegClass RealReg -> UniqFM VirtualReg VirtualReg -> SpillStats -> SpillCostInfo -> [LiveCmmDecl statics instr] -> !Platform -> RegAllocStats statics instr
- GHC.Driver.Main: HscRecomp :: CgGuts -> !ModLocation -> !ModDetails -> !PartialModIface -> !Maybe Fingerprint -> !DynFlags -> HscStatus
+ GHC.Driver.Main: HscRecomp :: CgGuts -> !ModLocation -> !ModDetails -> !PartialModIface -> !Maybe Fingerprint -> HscStatus
- GHC.Driver.Main: hscIncrementalCompile :: Bool -> Maybe TcGblEnv -> Maybe Messager -> HscEnv -> ModSummary -> SourceModified -> Maybe ModIface -> (Int, Int) -> IO (HscStatus, DynFlags)
+ GHC.Driver.Main: hscIncrementalCompile :: Bool -> Maybe TcGblEnv -> Maybe Messager -> HscEnv -> ModSummary -> SourceModified -> Maybe ModIface -> (Int, Int) -> IO (HscStatus, HscEnv)
- GHC.Driver.Main: hscMaybeWriteIface :: DynFlags -> ModIface -> Maybe Fingerprint -> ModLocation -> IO ()
+ GHC.Driver.Main: hscMaybeWriteIface :: DynFlags -> Bool -> ModIface -> Maybe Fingerprint -> ModLocation -> IO ()
- GHC.Rename.HsType: AlwaysBind :: HsSigWcTypeScoping
+ GHC.Rename.HsType: AlwaysBind :: HsPatSigTypeScoping
- GHC.Rename.HsType: NeverBind :: HsSigWcTypeScoping
+ GHC.Rename.HsType: NeverBind :: HsPatSigTypeScoping
- GHC.Rename.HsType: rnHsPatSigType :: HsSigWcTypeScoping -> HsDocContext -> HsPatSigType GhcPs -> (HsPatSigType GhcRn -> RnM (a, FreeVars)) -> RnM (a, FreeVars)
+ GHC.Rename.HsType: rnHsPatSigType :: HsPatSigTypeScoping -> HsDocContext -> HsPatSigType GhcPs -> (HsPatSigType GhcRn -> RnM (a, FreeVars)) -> RnM (a, FreeVars)
- GHC.Runtime.Loader: initializePlugins :: HscEnv -> DynFlags -> IO DynFlags
+ GHC.Runtime.Loader: initializePlugins :: HscEnv -> IO HscEnv
- GHC.Stg.Lift.Analysis: RhsSk :: !DmdShell -> !Skeleton -> Skeleton
+ GHC.Stg.Lift.Analysis: RhsSk :: !Card -> !Skeleton -> Skeleton
- GHC.StgToCmm.ArgRep: idArgRep :: Id -> ArgRep
+ GHC.StgToCmm.ArgRep: idArgRep :: Platform -> Id -> ArgRep
- GHC.StgToCmm.ArgRep: toArgRep :: PrimRep -> ArgRep
+ GHC.StgToCmm.ArgRep: toArgRep :: Platform -> PrimRep -> ArgRep
- GHC.StgToCmm.Layout: toArgRep :: PrimRep -> ArgRep
+ GHC.StgToCmm.Layout: toArgRep :: Platform -> PrimRep -> ArgRep
- GHC.Tc.Gen.HsType: addSigCtxt :: UserTypeCtxt -> LHsType GhcRn -> TcM a -> TcM a
+ GHC.Tc.Gen.HsType: addSigCtxt :: Outputable hs_ty => UserTypeCtxt -> Located hs_ty -> TcM a -> TcM a
- GHC.Tc.Gen.HsType: kcClassSigType :: SkolemInfo -> [Located Name] -> LHsSigType GhcRn -> TcM ()
+ GHC.Tc.Gen.HsType: kcClassSigType :: [Located Name] -> LHsSigType GhcRn -> TcM ()
- GHC.Tc.Gen.HsType: pprSigCtxt :: UserTypeCtxt -> LHsType GhcRn -> SDoc
+ GHC.Tc.Gen.HsType: pprSigCtxt :: Outputable hs_ty => UserTypeCtxt -> Located hs_ty -> SDoc
- GHC.Tc.Gen.HsType: tcClassSigType :: SkolemInfo -> [Located Name] -> LHsSigType GhcRn -> TcM Type
+ GHC.Tc.Gen.HsType: tcClassSigType :: [Located Name] -> LHsSigType GhcRn -> TcM Type
Files
- compiler/GHC.hs +20/−8
- compiler/GHC/ByteCode/Asm.hs +9/−0
- compiler/GHC/Cmm/Info/Build.hs +3/−4
- compiler/GHC/Cmm/Sink.hs +11/−4
- compiler/GHC/CmmToAsm.hs +44/−44
- compiler/GHC/CmmToAsm/Dwarf.hs +12/−9
- compiler/GHC/CmmToAsm/Dwarf/Constants.hs +2/−2
- compiler/GHC/CmmToAsm/Dwarf/Types.hs +22/−8
- compiler/GHC/CmmToAsm/Monad.hs +7/−6
- compiler/GHC/CmmToAsm/PIC.hs +21/−26
- compiler/GHC/CmmToAsm/Ppr.hs +11/−3
- compiler/GHC/CmmToAsm/Reg/Graph.hs +2/−1
- compiler/GHC/CmmToAsm/Reg/Graph/Stats.hs +5/−1
- compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs +3/−3
- compiler/GHC/CmmToAsm/Reg/Linear.hs +1/−1
- compiler/GHC/CmmToAsm/Reg/Linear/FreeRegs.hs +1/−1
- compiler/GHC/CmmToAsm/Reg/Target.hs +5/−5
- compiler/GHC/CmmToAsm/X86/CodeGen.hs +95/−21
- compiler/GHC/CmmToAsm/X86/Cond.hs +16/−16
- compiler/GHC/CmmToAsm/X86/Ppr.hs +30/−9
- compiler/GHC/CmmToC.hs +79/−102
- compiler/GHC/CmmToLlvm/Base.hs +7/−2
- compiler/GHC/Core/Opt/CprAnal.hs +1/−1
- compiler/GHC/Core/Opt/DmdAnal.hs +161/−126
- compiler/GHC/Core/Opt/Pipeline.hs +16/−10
- compiler/GHC/Core/Opt/SetLevels.hs +2/−2
- compiler/GHC/Core/Opt/Simplify.hs +11/−11
- compiler/GHC/Core/Opt/Simplify/Utils.hs +5/−5
- compiler/GHC/Core/Opt/SpecConstr.hs +7/−6
- compiler/GHC/Core/Opt/WorkWrap/Utils.hs +7/−8
- compiler/GHC/CoreToByteCode.hs +81/−46
- compiler/GHC/CoreToStg.hs +5/−5
- compiler/GHC/CoreToStg/Prep.hs +2/−2
- compiler/GHC/Driver/Backpack.hs +6/−3
- compiler/GHC/Driver/CodeOutput.hs +7/−1
- compiler/GHC/Driver/Main.hs +139/−91
- compiler/GHC/Driver/Make.hs +10/−9
- compiler/GHC/Driver/MakeFile.hs +5/−5
- compiler/GHC/Driver/Pipeline.hs +102/−403
- compiler/GHC/HsToCore.hs +1/−1
- compiler/GHC/HsToCore/Docs.hs +15/−15
- compiler/GHC/HsToCore/Foreign/Call.hs +4/−30
- compiler/GHC/HsToCore/Foreign/Decl.hs +10/−4
- compiler/GHC/HsToCore/Pmc.hs +4/−1
- compiler/GHC/HsToCore/Pmc/Ppr.hs +2/−15
- compiler/GHC/HsToCore/Quote.hs +118/−104
- compiler/GHC/HsToCore/Usage.hs +3/−1
- compiler/GHC/Iface/Ext/Ast.hs +37/−43
- compiler/GHC/Iface/Load.hs +30/−22
- compiler/GHC/Iface/Make.hs +2/−2
- compiler/GHC/Iface/Recomp.hs +99/−11
- compiler/GHC/Iface/Recomp/Flags.hs +2/−2
- compiler/GHC/Iface/Tidy/StaticPtrTable.hs +2/−1
- compiler/GHC/IfaceToCore.hs +11/−14
- compiler/GHC/Linker.hs +36/−0
- compiler/GHC/Linker/Dynamic.hs +264/−0
- compiler/GHC/Linker/ExtraObj.hs +260/−0
- compiler/GHC/Linker/Loader.hs +1720/−0
- compiler/GHC/Linker/MacOS.hs +183/−0
- compiler/GHC/Linker/Static.hs +341/−0
- compiler/GHC/Linker/Unit.hs +134/−0
- compiler/GHC/Linker/Windows.hs +64/−0
- compiler/GHC/Rename/HsType.hs +76/−113
- compiler/GHC/Rename/Module.hs +64/−82
- compiler/GHC/Rename/Names.hs +1/−2
- compiler/GHC/Rename/Utils.hs +4/−7
- compiler/GHC/Runtime/Debugger.hs +6/−5
- compiler/GHC/Runtime/Eval.hs +15/−16
- compiler/GHC/Runtime/Heap/Inspect.hs +5/−1
- compiler/GHC/Runtime/Interpreter.hs +4/−3
- compiler/GHC/Runtime/Linker.hs +0/−1802
- compiler/GHC/Runtime/Loader.hs +18/−17
- compiler/GHC/Stg/Lift/Analysis.hs +20/−30
- compiler/GHC/StgToCmm/ArgRep.hs +29/−24
- compiler/GHC/StgToCmm/DataCon.hs +16/−1
- compiler/GHC/StgToCmm/Layout.hs +6/−4
- compiler/GHC/StgToCmm/Prim.hs +129/−71
- compiler/GHC/StgToCmm/Ticky.hs +4/−3
- compiler/GHC/StgToCmm/Utils.hs +6/−0
- compiler/GHC/SysTools.hs +1/−297
- compiler/GHC/SysTools/ExtraObj.hs +0/−251
- compiler/GHC/SysTools/Tasks.hs +0/−37
- compiler/GHC/Tc/Deriv.hs +8/−11
- compiler/GHC/Tc/Deriv/Generate.hs +11/−12
- compiler/GHC/Tc/Errors.hs +8/−3
- compiler/GHC/Tc/Errors/Hole.hs +1/−1
- compiler/GHC/Tc/Gen/App.hs +4/−4
- compiler/GHC/Tc/Gen/Bind.hs +1/−1
- compiler/GHC/Tc/Gen/Foreign.hs +1/−1
- compiler/GHC/Tc/Gen/Head.hs +1/−1
- compiler/GHC/Tc/Gen/HsType.hs +487/−302
- compiler/GHC/Tc/Gen/Pat.hs +12/−0
- compiler/GHC/Tc/Gen/Sig.hs +58/−61
- compiler/GHC/Tc/Gen/Splice.hs +3/−3
- compiler/GHC/Tc/Instance/Typeable.hs +1/−1
- compiler/GHC/Tc/Module.hs +35/−37
- compiler/GHC/Tc/Solver.hs +36/−14
- compiler/GHC/Tc/Solver/Canonical.hs +4/−4
- compiler/GHC/Tc/Solver/Flatten.hs +1/−1
- compiler/GHC/Tc/TyCl.hs +89/−81
- compiler/GHC/Tc/TyCl/Class.hs +4/−6
- compiler/GHC/Tc/TyCl/Instance.hs +19/−22
- compiler/GHC/Tc/TyCl/PatSyn.hs +81/−23
- compiler/GHC/Tc/Utils/Backpack.hs +2/−2
- compiler/GHC/Tc/Utils/Env.hs +2/−2
- compiler/GHC/Tc/Utils/Instantiate.hs +24/−7
- compiler/GHC/Tc/Utils/Monad.hs +11/−6
- compiler/GHC/Tc/Utils/Unify.hs +10/−5
- compiler/GHC/Tc/Validity.hs +9/−9
- compiler/GHC/ThToHs.hs +75/−51
- compiler/GHC/Unit/Finder.hs +1/−1
- ghc-lib.cabal +21/−6
- ghc-lib/stage0/compiler/build/primop-can-fail.hs-incl +12/−0
- ghc-lib/stage0/compiler/build/primop-commutable.hs-incl +6/−6
- ghc-lib/stage0/compiler/build/primop-data-decl.hs-incl +36/−24
- ghc-lib/stage0/compiler/build/primop-docs.hs-incl +17/−9
- ghc-lib/stage0/compiler/build/primop-has-side-effects.hs-incl +11/−3
- ghc-lib/stage0/compiler/build/primop-list.hs-incl +36/−24
- ghc-lib/stage0/compiler/build/primop-primop-info.hs-incl +37/−25
- ghc-lib/stage0/compiler/build/primop-strictness.hs-incl +4/−8
- ghc-lib/stage0/compiler/build/primop-tag.hs-incl +1226/−1214
- ghc-lib/stage0/lib/ghcversion.h +2/−2
- ghc-lib/stage0/lib/llvm-targets +25/−24
- includes/CodeGen.Platform.hs +1/−2
- libraries/ghci/GHCi/InfoTable.hsc +3/−3
- libraries/ghci/GHCi/Run.hs +3/−3
compiler/GHC.hs view
@@ -215,7 +215,7 @@ FamInst, -- ** Types and Kinds- Type, splitForAllTys, funResultTy,+ Type, splitForAllTyCoVars, funResultTy, pprParendType, pprTypeApp, Kind, PredType,@@ -313,6 +313,7 @@ import GHC.Driver.Ppr import GHC.ByteCode.Types+import GHC.Runtime.Loader import GHC.Runtime.Eval import GHC.Runtime.Eval.Types import GHC.Runtime.Interpreter@@ -621,12 +622,6 @@ -- read), and prepares the compilers knowledge about packages. It can -- be called again to load new packages: just add new package flags to -- (packageFlags dflags).------ Returns a list of new packages that may need to be linked in using--- the dynamic linker (see 'linkPackages') as a result of new package--- flags. If you are not doing linking or doing static linking, you--- can ignore the list of packages returned.--- setSessionDynFlags :: GhcMonad m => DynFlags -> m () setSessionDynFlags dflags0 = do dflags1 <- checkNewDynFlags dflags0@@ -735,6 +730,8 @@ getProgramDynFlags = getSessionDynFlags -- | Set the 'DynFlags' used to evaluate interactive expressions.+-- Also initialise (load) plugins.+-- -- Note: this cannot be used for changes to packages. Use -- 'setSessionDynFlags', or 'setProgramDynFlags' and then copy the -- 'unitState' into the interactive @DynFlags@.@@ -742,7 +739,22 @@ setInteractiveDynFlags dflags = do dflags' <- checkNewDynFlags dflags dflags'' <- checkNewInteractiveDynFlags dflags'- modifySession $ \h -> h{ hsc_IC = (hsc_IC h) { ic_dflags = dflags'' }}+ modifySessionM $ \hsc_env0 -> do+ let ic0 = hsc_IC hsc_env0++ -- Initialise (load) plugins in the interactive environment with the new+ -- DynFlags+ plugin_env <- liftIO $ initializePlugins $ mkInteractiveHscEnv $+ hsc_env0 { hsc_IC = ic0 { ic_dflags = dflags'' }}++ -- Update both plugins cache and DynFlags in the interactive context.+ return $ hsc_env0+ { hsc_IC = ic0+ { ic_plugins = hsc_plugins plugin_env+ , ic_dflags = hsc_dflags plugin_env+ }+ }+ -- | Get the 'DynFlags' used to evaluate interactive expressions. getInteractiveDynFlags :: GhcMonad m => m DynFlags
compiler/GHC/ByteCode/Asm.hs view
@@ -464,6 +464,12 @@ literal (LitNumber nt i) = case nt of LitNumInt -> int (fromIntegral i) LitNumWord -> int (fromIntegral i)+ LitNumInt8 -> int8 (fromIntegral i)+ LitNumWord8 -> int8 (fromIntegral i)+ LitNumInt16 -> int16 (fromIntegral i)+ LitNumWord16 -> int16 (fromIntegral i)+ LitNumInt32 -> int32 (fromIntegral i)+ LitNumWord32 -> int32 (fromIntegral i) LitNumInt64 -> int64 (fromIntegral i) LitNumWord64 -> int64 (fromIntegral i) LitNumInteger -> panic "GHC.ByteCode.Asm.literal: LitNumInteger"@@ -478,6 +484,9 @@ float = words . mkLitF double = words . mkLitD platform int = words . mkLitI+ int8 = words . mkLitI64 platform+ int16 = words . mkLitI64 platform+ int32 = words . mkLitI64 platform int64 = words . mkLitI64 platform words ws = lit (map BCONPtrWord ws) word w = words [w]
compiler/GHC/Cmm/Info/Build.hs view
@@ -946,7 +946,8 @@ topSRT <- get let- config = initNCGConfig dflags+ this_mod = thisModule topSRT+ config = initNCGConfig dflags this_mod profile = targetProfile dflags platform = profilePlatform profile srtMap = moduleSRTMap topSRT@@ -1019,8 +1020,6 @@ in state{ moduleSRTMap = srt_map } - this_mod = thisModule topSRT- allStaticData = all (\(CAFLabel clbl) -> Set.member clbl static_data) caf_lbls @@ -1048,7 +1047,7 @@ -- when dynamic linking is used we cannot guarantee that the offset -- between the SRT and the info table will fit in the offset field. -- Consequently we build a singleton SRT in this case.- not (labelDynamic config this_mod lbl)+ not (labelDynamic config lbl) -- MachO relocations can't express offsets between compilation units at -- all, so we are always forced to build a singleton SRT in this case.
compiler/GHC/Cmm/Sink.hs view
@@ -449,6 +449,7 @@ || l `elemLRegSet` skipped || not (okToInline platform rhs node) + -- How often is l used in the current node. l_usages = lookupUFM usages l l_live = l `elemRegSet` live @@ -554,10 +555,16 @@ regsUsedIn :: LRegSet -> CmmExpr -> Bool regsUsedIn ls _ | nullLRegSet ls = False-regsUsedIn ls e = wrapRecExpf f e False- where f (CmmReg (CmmLocal l)) _ | l `elemLRegSet` ls = True- f (CmmRegOff (CmmLocal l) _) _ | l `elemLRegSet` ls = True- f _ z = z+regsUsedIn ls e = go ls e False+ where use :: LRegSet -> CmmExpr -> Bool -> Bool+ use ls (CmmReg (CmmLocal l)) _ | l `elemLRegSet` ls = True+ use ls (CmmRegOff (CmmLocal l) _) _ | l `elemLRegSet` ls = True+ use _ls _ z = z++ go :: LRegSet -> CmmExpr -> Bool -> Bool+ go ls (CmmMachOp _ es) z = foldr (go ls) z es+ go ls (CmmLoad addr _) z = go ls addr z+ go ls e z = use ls e z -- we don't inline into CmmUnsafeForeignCall if the expression refers -- to global registers. This is a HACK to avoid global registers
compiler/GHC/CmmToAsm.hs view
@@ -152,11 +152,11 @@ -> Stream IO RawCmmGroup a -> IO a nativeCodeGen dflags this_mod modLoc h us cmms- = let config = initNCGConfig dflags+ = let config = initNCGConfig dflags this_mod platform = ncgPlatform config nCG' :: ( OutputableP Platform statics, Outputable jumpDest, Instruction instr) => NcgImpl statics instr jumpDest -> IO a- nCG' ncgImpl = nativeCodeGen' dflags config this_mod modLoc ncgImpl h us cmms+ nCG' ncgImpl = nativeCodeGen' dflags config modLoc ncgImpl h us cmms in case platformArch platform of ArchX86 -> nCG' (X86.ncgX86 config) ArchX86_64 -> nCG' (X86.ncgX86_64 config)@@ -166,7 +166,7 @@ ArchSPARC64 -> panic "nativeCodeGen: No NCG for SPARC64" ArchS390X -> panic "nativeCodeGen: No NCG for S390X" ArchARM {} -> panic "nativeCodeGen: No NCG for ARM"- ArchARM64 -> panic "nativeCodeGen: No NCG for ARM64"+ ArchAArch64 -> panic "nativeCodeGen: No NCG for AArch64" ArchAlpha -> panic "nativeCodeGen: No NCG for Alpha" ArchMipseb -> panic "nativeCodeGen: No NCG for mipseb" ArchMipsel -> panic "nativeCodeGen: No NCG for mipsel"@@ -221,20 +221,20 @@ nativeCodeGen' :: (OutputableP Platform statics, Outputable jumpDest, Instruction instr) => DynFlags -> NCGConfig- -> Module -> ModLocation+ -> ModLocation -> NcgImpl statics instr jumpDest -> Handle -> UniqSupply -> Stream IO RawCmmGroup a -> IO a-nativeCodeGen' dflags config this_mod modLoc ncgImpl h us cmms+nativeCodeGen' dflags config modLoc ncgImpl h us cmms = do -- BufHandle is a performance hack. We could hide it inside -- Pretty if it weren't for the fact that we do lots of little -- printDocs here (in order to do codegen in constant space). bufh <- newBufHandle h let ngs0 = NGS [] [] [] [] [] [] emptyUFM mapEmpty- (ngs, us', a) <- cmmNativeGenStream dflags config this_mod modLoc ncgImpl bufh us+ (ngs, us', a) <- cmmNativeGenStream dflags config modLoc ncgImpl bufh us cmms ngs0 _ <- finishNativeGen dflags config modLoc bufh us' ngs return a@@ -290,7 +290,7 @@ -- write out the imports let ctx = ncgAsmContext config printSDocLn ctx Pretty.LeftMode h- $ makeImportsDoc dflags (concat (ngs_imports ngs))+ $ makeImportsDoc config (concat (ngs_imports ngs)) return us' where dump_stats = dumpAction dflags (mkDumpStyle alwaysQualify)@@ -300,7 +300,7 @@ cmmNativeGenStream :: (OutputableP Platform statics, Outputable jumpDest, Instruction instr) => DynFlags -> NCGConfig- -> Module -> ModLocation+ -> ModLocation -> NcgImpl statics instr jumpDest -> BufHandle -> UniqSupply@@ -308,7 +308,7 @@ -> NativeGenAcc statics instr -> IO (NativeGenAcc statics instr, UniqSupply, a) -cmmNativeGenStream dflags config this_mod modLoc ncgImpl h us cmm_stream ngs+cmmNativeGenStream dflags config modLoc ncgImpl h us cmm_stream ngs = do r <- Stream.runStream cmm_stream case r of Left a ->@@ -330,7 +330,7 @@ dbgMap = debugToMap ndbgs -- Generate native code- (ngs',us') <- cmmNativeGens dflags config this_mod modLoc ncgImpl h+ (ngs',us') <- cmmNativeGens dflags config modLoc ncgImpl h dbgMap us cmms ngs 0 -- Link native code information into debug blocks@@ -345,7 +345,7 @@ let ngs'' = ngs' { ngs_debug = ngs_debug ngs' ++ ldbgs, ngs_labels = [] } return (us', ngs'') - cmmNativeGenStream dflags config this_mod modLoc ncgImpl h us'+ cmmNativeGenStream dflags config modLoc ncgImpl h us' cmm_stream' ngs'' where ncglabel = text "NCG"@@ -356,7 +356,7 @@ (OutputableP Platform statics, Outputable jumpDest, Instruction instr) => DynFlags -> NCGConfig- -> Module -> ModLocation+ -> ModLocation -> NcgImpl statics instr jumpDest -> BufHandle -> LabelMap DebugBlock@@ -366,7 +366,7 @@ -> Int -> IO (NativeGenAcc statics instr, UniqSupply) -cmmNativeGens dflags config this_mod modLoc ncgImpl h dbgMap = go+cmmNativeGens dflags config modLoc ncgImpl h dbgMap = go where go :: UniqSupply -> [RawCmmDecl] -> NativeGenAcc statics instr -> Int@@ -379,7 +379,7 @@ let fileIds = ngs_dwarfFiles ngs (us', fileIds', native, imports, colorStats, linearStats, unwinds) <- {-# SCC "cmmNativeGen" #-}- cmmNativeGen dflags this_mod modLoc ncgImpl us fileIds dbgMap+ cmmNativeGen dflags modLoc ncgImpl us fileIds dbgMap cmm count -- Generate .file directives for every new file that has been@@ -433,7 +433,7 @@ cmmNativeGen :: forall statics instr jumpDest. (Instruction instr, OutputableP Platform statics, Outputable jumpDest) => DynFlags- -> Module -> ModLocation+ -> ModLocation -> NcgImpl statics instr jumpDest -> UniqSupply -> DwarfFiles@@ -449,7 +449,7 @@ , LabelMap [UnwindPoint] -- unwinding information for blocks ) -cmmNativeGen dflags this_mod modLoc ncgImpl us fileIds dbgMap cmm count+cmmNativeGen dflags modLoc ncgImpl us fileIds dbgMap cmm count = do let config = ncgConfig ncgImpl let platform = ncgPlatform config@@ -467,7 +467,7 @@ -- cmm to cmm optimisations let (opt_cmm, imports) = {-# SCC "cmmToCmm" #-}- cmmToCmm config this_mod fixed_cmm+ cmmToCmm config fixed_cmm dumpIfSet_dyn dflags Opt_D_dump_opt_cmm "Optimised Cmm" FormatCMM@@ -479,7 +479,7 @@ -- generate native code from cmm let ((native, lastMinuteImports, fileIds', nativeCfgWeights), usGen) = {-# SCC "genMachCode" #-}- initUs us $ genMachCode config this_mod modLoc+ initUs us $ genMachCode config modLoc (cmmTopCodeGen ncgImpl) fileIds dbgMap opt_cmm cmmCfg @@ -750,8 +750,8 @@ -- | Build a doc for all the imports. ---makeImportsDoc :: DynFlags -> [CLabel] -> SDoc-makeImportsDoc dflags imports+makeImportsDoc :: NCGConfig -> [CLabel] -> SDoc+makeImportsDoc config imports = dyld_stubs imports $$ -- On recent versions of Darwin, the linker supports@@ -779,7 +779,6 @@ else Outputable.empty) where- config = initNCGConfig dflags platform = ncgPlatform config -- Generate "symbol stubs" for all external symbols that might@@ -915,7 +914,7 @@ genMachCode :: NCGConfig- -> Module -> ModLocation+ -> ModLocation -> (RawCmmDecl -> NatM [NatCmmDecl statics instr]) -> DwarfFiles -> LabelMap DebugBlock@@ -928,9 +927,9 @@ , CFG ) -genMachCode config this_mod modLoc cmmTopCodeGen fileIds dbgMap cmm_top cmm_cfg+genMachCode config modLoc cmmTopCodeGen fileIds dbgMap cmm_top cmm_cfg = do { initial_us <- getUniqueSupplyM- ; let initial_st = mkNatM_State initial_us 0 config this_mod+ ; let initial_st = mkNatM_State initial_us 0 config modLoc fileIds dbgMap cmm_cfg (new_tops, final_st) = initNat initial_st (cmmTopCodeGen cmm_top) final_delta = natm_delta final_st@@ -967,10 +966,10 @@ temp assignments, and certain assigns to mem...) -} -cmmToCmm :: NCGConfig -> Module -> RawCmmDecl -> (RawCmmDecl, [CLabel])-cmmToCmm _ _ top@(CmmData _ _) = (top, [])-cmmToCmm config this_mod (CmmProc info lbl live graph)- = runCmmOpt config this_mod $+cmmToCmm :: NCGConfig -> RawCmmDecl -> (RawCmmDecl, [CLabel])+cmmToCmm _ top@(CmmData _ _) = (top, [])+cmmToCmm config (CmmProc info lbl live graph)+ = runCmmOpt config $ do blocks' <- mapM cmmBlockConFold (toBlockList graph) return $ CmmProc info lbl live (ofBlockList (g_entry graph) blocks') @@ -987,34 +986,33 @@ data OptMResult a = OptMResult !a ![CLabel] deriving (Functor) #endif -newtype CmmOptM a = CmmOptM (NCGConfig -> Module -> [CLabel] -> OptMResult a)+newtype CmmOptM a = CmmOptM (NCGConfig -> [CLabel] -> OptMResult a) deriving (Functor) instance Applicative CmmOptM where- pure x = CmmOptM $ \_ _ imports -> OptMResult x imports+ pure x = CmmOptM $ \_ imports -> OptMResult x imports (<*>) = ap instance Monad CmmOptM where (CmmOptM f) >>= g =- CmmOptM $ \config this_mod imports0 ->- case f config this_mod imports0 of+ CmmOptM $ \config imports0 ->+ case f config imports0 of OptMResult x imports1 -> case g x of- CmmOptM g' -> g' config this_mod imports1+ CmmOptM g' -> g' config imports1 instance CmmMakeDynamicReferenceM CmmOptM where addImport = addImportCmmOpt- getThisModule = CmmOptM $ \_ this_mod imports -> OptMResult this_mod imports addImportCmmOpt :: CLabel -> CmmOptM ()-addImportCmmOpt lbl = CmmOptM $ \_ _ imports -> OptMResult () (lbl:imports)+addImportCmmOpt lbl = CmmOptM $ \_ imports -> OptMResult () (lbl:imports) getCmmOptConfig :: CmmOptM NCGConfig-getCmmOptConfig = CmmOptM $ \config _ imports -> OptMResult config imports+getCmmOptConfig = CmmOptM $ \config imports -> OptMResult config imports -runCmmOpt :: NCGConfig -> Module -> CmmOptM a -> (a, [CLabel])-runCmmOpt config this_mod (CmmOptM f) =- case f config this_mod [] of+runCmmOpt :: NCGConfig -> CmmOptM a -> (a, [CLabel])+runCmmOpt config (CmmOptM f) =+ case f config [] of OptMResult result imports -> (result, imports) cmmBlockConFold :: CmmBlock -> CmmOptM CmmBlock@@ -1144,9 +1142,10 @@ -> return other -- | Initialize the native code generator configuration from the DynFlags-initNCGConfig :: DynFlags -> NCGConfig-initNCGConfig dflags = NCGConfig+initNCGConfig :: DynFlags -> Module -> NCGConfig+initNCGConfig dflags this_mod = NCGConfig { ncgPlatform = targetPlatform dflags+ , ncgThisModule = this_mod , ncgAsmContext = initSDocContext dflags (PprCode AsmStyle) , ncgProcAlignment = cmmProcAlignment dflags , ncgExternalDynamicRefs = gopt Opt_ExternalDynamicRefs dflags@@ -1188,8 +1187,9 @@ ArchX86 -> v _ -> Nothing - , ncgDwarfEnabled = debugLevel dflags > 0+ , ncgDwarfEnabled = debugLevel dflags > 0 , ncgDwarfUnwindings = debugLevel dflags >= 1- , ncgDwarfStripBlockInfo = debugLevel dflags < 2 -- We strip out block information when running with -g0 or -g1.+ , ncgExposeInternalSymbols = gopt Opt_ExposeInternalSymbols dflags+ , ncgDwarfStripBlockInfo = debugLevel dflags < 2 -- We strip out block information when running with -g0 or -g1.+ , ncgDwarfSourceNotes = debugLevel dflags >= 3 -- We produce GHC-specific source-note DIEs only with -g3 }-
compiler/GHC/CmmToAsm/Dwarf.hs view
@@ -45,7 +45,7 @@ | otherwise = dbg compPath <- getCurrentDirectory let lowLabel = dblCLabel $ head procs- highLabel = mkAsmTempEndLabel $ dblCLabel $ last procs+ highLabel = mkAsmTempProcEndLabel $ dblCLabel $ last procs dwarfUnit = DwarfCompileUnit { dwChildren = map (procToDwarf config) (map stripBlocks procs) , dwName = fromMaybe "" (ml_hs_file modLoc)@@ -99,10 +99,10 @@ -- scattered in the final binary. Without split sections, we could make a -- single arange based on the first/last proc. mkDwarfARange :: DebugBlock -> DwarfARange-mkDwarfARange proc = DwarfARange start end+mkDwarfARange proc = DwarfARange lbl end where- start = dblCLabel proc- end = mkAsmTempEndLabel start+ lbl = dblCLabel proc+ end = mkAsmTempProcEndLabel lbl -- | Header for a compilation unit, establishing global format -- parameters@@ -176,7 +176,7 @@ -- | Generate DWARF info for a procedure debug block procToDwarf :: NCGConfig -> DebugBlock -> DwarfInfo procToDwarf config prc- = DwarfSubprogram { dwChildren = map blockToDwarf (dblBlocks prc)+ = DwarfSubprogram { dwChildren = map (blockToDwarf config) (dblBlocks prc) , dwName = case dblSourceTick prc of Just s@SourceNote{} -> sourceName s _otherwise -> show (dblLabel prc)@@ -195,14 +195,17 @@ goodParent _ = True -- | Generate DWARF info for a block-blockToDwarf :: DebugBlock -> DwarfInfo-blockToDwarf blk- = DwarfBlock { dwChildren = concatMap tickToDwarf (dblTicks blk)- ++ map blockToDwarf (dblBlocks blk)+blockToDwarf :: NCGConfig -> DebugBlock -> DwarfInfo+blockToDwarf config blk+ = DwarfBlock { dwChildren = map (blockToDwarf config) (dblBlocks blk) ++ srcNotes , dwLabel = dblCLabel blk , dwMarker = marker } where+ srcNotes+ | ncgDwarfSourceNotes config = concatMap tickToDwarf (dblTicks blk)+ | otherwise = []+ marker | Just _ <- dblPosition blk = Just $ mkAsmTempLabel $ dblLabel blk | otherwise = Nothing -- block was optimized out
compiler/GHC/CmmToAsm/Dwarf/Constants.hs view
@@ -48,7 +48,7 @@ -- * Dwarf attributes dW_AT_name, dW_AT_stmt_list, dW_AT_low_pc, dW_AT_high_pc, dW_AT_language, dW_AT_comp_dir, dW_AT_producer, dW_AT_external, dW_AT_frame_base,- dW_AT_use_UTF8, dW_AT_MIPS_linkage_name :: Word+ dW_AT_use_UTF8, dW_AT_linkage_name :: Word dW_AT_name = 0x03 dW_AT_stmt_list = 0x10 dW_AT_low_pc = 0x11@@ -59,7 +59,7 @@ dW_AT_external = 0x3f dW_AT_frame_base = 0x40 dW_AT_use_UTF8 = 0x53-dW_AT_MIPS_linkage_name = 0x2007+dW_AT_linkage_name = 0x6e -- * Custom DWARF attributes -- Chosen a more or less random section of the vendor-extensible region
compiler/GHC/CmmToAsm/Dwarf/Types.hs view
@@ -105,7 +105,7 @@ -- DwAbbrSubprogramWithParent subprogramAttrs = [ (dW_AT_name, dW_FORM_string)- , (dW_AT_MIPS_linkage_name, dW_FORM_string)+ , (dW_AT_linkage_name, dW_FORM_string) , (dW_AT_external, dW_FORM_flag) , (dW_AT_low_pc, dW_FORM_addr) , (dW_AT_high_pc, dW_FORM_addr)@@ -178,7 +178,8 @@ $$ pprString producer $$ pprData4 dW_LANG_Haskell $$ pprString compDir- $$ pprWord platform (pdoc platform lowLabel)+ -- Offset due to Note [Info Offset]+ $$ pprWord platform (pdoc platform lowLabel <> text "-1") $$ pprWord platform (pdoc platform highLabel) $$ if haveSrc then sectionOffset platform (ptext lineLbl) (ptext dwarfLineLabel)@@ -189,8 +190,9 @@ $$ pprString name $$ pprLabelString platform label $$ pprFlag (externallyVisibleCLabel label)- $$ pprWord platform (pdoc platform label)- $$ pprWord platform (pdoc platform $ mkAsmTempEndLabel label)+ -- Offset due to Note [Info Offset]+ $$ pprWord platform (pdoc platform label <> text "-1")+ $$ pprWord platform (pdoc platform $ mkAsmTempProcEndLabel label) $$ pprByte 1 $$ pprByte dW_OP_call_frame_cfa $$ parentValue@@ -256,7 +258,10 @@ $$ pprWord platform (char '0') pprDwarfARange :: Platform -> DwarfARange -> SDoc-pprDwarfARange platform arng = pprWord platform (pdoc platform $ dwArngStartLabel arng) $$ pprWord platform length+pprDwarfARange platform arng =+ -- Offset due to Note [Info offset].+ pprWord platform (pdoc platform (dwArngStartLabel arng) <> text "-1")+ $$ pprWord platform length where length = pdoc platform (dwArngEndLabel arng) <> char '-' <> pdoc platform (dwArngStartLabel arng)@@ -354,9 +359,9 @@ pprFrameProc platform frameLbl initUw (DwarfFrameProc procLbl hasInfo blocks) = let fdeLabel = mkAsmTempDerivedLabel procLbl (fsLit "_fde") fdeEndLabel = mkAsmTempDerivedLabel procLbl (fsLit "_fde_end")- procEnd = mkAsmTempEndLabel procLbl+ procEnd = mkAsmTempProcEndLabel procLbl ifInfo str = if hasInfo then text str else empty- -- see [Note: Info Offset]+ -- see Note [Info Offset] in vcat [ whenPprDebug $ text "# Unwinding for" <+> pdoc platform procLbl <> colon , pprData4' (pdoc platform fdeEndLabel <> char '-' <> pdoc platform fdeLabel) , pdoc platform fdeLabel <> colon@@ -398,7 +403,7 @@ in if oldUws == uws then (empty, oldUws)- else let -- see [Note: Info Offset]+ else let -- see Note [Info Offset] needsOffset = firstDecl && hasInfo lblDoc = pdoc platform lbl <> if needsOffset then text "-1" else empty@@ -407,6 +412,7 @@ in (doc, uws) -- Note [Info Offset]+-- ~~~~~~~~~~~~~~~~~~ -- -- GDB was pretty much written with C-like programs in mind, and as a -- result they assume that once you have a return address, it is a@@ -425,6 +431,14 @@ -- Note that this will not prevent GDB from failing to look-up the -- correct function name for the frame, as that uses the symbol table, -- which we can not manipulate as easily.+--+-- We apply this offset in several places:+--+-- * unwind information in .debug_frames+-- * the subprogram and lexical_block DIEs in .debug_info+-- * the ranges in .debug_aranges+--+-- In the latter two cases we apply the offset unconditionally. -- -- There's a GDB patch to address this at [1]. At the moment of writing -- it's not merged, so I recommend building GDB with the patch if you
compiler/GHC/CmmToAsm/Monad.hs view
@@ -80,6 +80,8 @@ canShortcut :: instr -> Maybe jumpDest, shortcutStatics :: (BlockId -> Maybe jumpDest) -> statics -> statics, shortcutJump :: (BlockId -> Maybe jumpDest) -> instr -> instr,+ -- | 'Module' is only for printing internal labels. See Note [Internal proc+ -- labels] in CLabel. pprNatCmmDecl :: NatCmmDecl statics instr -> SDoc, maxSpillSlots :: Int, allocatableRegs :: [RealReg],@@ -107,7 +109,6 @@ natm_imports :: [(CLabel)], natm_pic :: Maybe Reg, natm_config :: NCGConfig,- natm_this_module :: Module, natm_modloc :: ModLocation, natm_fileid :: DwarfFiles, natm_debug_map :: LabelMap DebugBlock,@@ -125,9 +126,9 @@ unNat :: NatM a -> NatM_State -> (a, NatM_State) unNat (NatM a) = a -mkNatM_State :: UniqSupply -> Int -> NCGConfig -> Module -> ModLocation ->+mkNatM_State :: UniqSupply -> Int -> NCGConfig -> ModLocation -> DwarfFiles -> LabelMap DebugBlock -> CFG -> NatM_State-mkNatM_State us delta config this_mod+mkNatM_State us delta config = \loc dwf dbg cfg -> NatM_State { natm_us = us@@ -135,7 +136,6 @@ , natm_imports = [] , natm_pic = Nothing , natm_config = config- , natm_this_module = this_mod , natm_modloc = loc , natm_fileid = dwf , natm_debug_map = dbg@@ -198,10 +198,11 @@ setDeltaNat :: Int -> NatM () setDeltaNat delta = NatM $ \ st -> ((), st {natm_delta = delta}) - getThisModuleNat :: NatM Module-getThisModuleNat = NatM $ \ st -> (natm_this_module st, st)+getThisModuleNat = NatM $ \ st -> (ncgThisModule $ natm_config st, st) +instance HasModule NatM where+ getModule = getThisModuleNat addImportNat :: CLabel -> NatM () addImportNat imp
compiler/GHC/CmmToAsm/PIC.hs view
@@ -65,7 +65,6 @@ import GHC.Cmm.CLabel import GHC.Types.Basic-import GHC.Unit.Module import GHC.Utils.Outputable import GHC.Utils.Panic@@ -95,11 +94,9 @@ class Monad m => CmmMakeDynamicReferenceM m where addImport :: CLabel -> m ()- getThisModule :: m Module instance CmmMakeDynamicReferenceM NatM where addImport = addImportNat- getThisModule = getThisModuleNat cmmMakeDynamicReference :: CmmMakeDynamicReferenceM m@@ -113,13 +110,11 @@ = return $ CmmLit $ CmmLabel lbl -- already processed it, pass through | otherwise- = do this_mod <- getThisModule- let platform = ncgPlatform config+ = do let platform = ncgPlatform config case howToAccessLabel config (platformArch platform) (platformOS platform)- this_mod referenceKind lbl of AccessViaStub -> do@@ -208,7 +203,7 @@ | AccessViaSymbolPtr | AccessDirectly -howToAccessLabel :: NCGConfig -> Arch -> OS -> Module -> ReferenceKind -> CLabel -> LabelAccessStyle+howToAccessLabel :: NCGConfig -> Arch -> OS -> ReferenceKind -> CLabel -> LabelAccessStyle -- Windows -- In Windows speak, a "module" is a set of objects linked into the@@ -231,7 +226,7 @@ -- into the same .exe file. In this case we always access symbols directly, -- and never use __imp_SYMBOL. ---howToAccessLabel config _ OSMinGW32 this_mod _ lbl+howToAccessLabel config _arch OSMinGW32 _kind lbl -- Assume all symbols will be in the same PE, so just access them directly. | not (ncgExternalDynamicRefs config)@@ -239,7 +234,7 @@ -- If the target symbol is in another PE we need to access it via the -- appropriate __imp_SYMBOL pointer.- | labelDynamic config this_mod lbl+ | labelDynamic config lbl = AccessViaSymbolPtr -- Target symbol is in the same PE as the caller, so just access it directly.@@ -255,9 +250,9 @@ -- It is always possible to access something indirectly, -- even when it's not necessary. ---howToAccessLabel config arch OSDarwin this_mod DataReference lbl+howToAccessLabel config arch OSDarwin DataReference lbl -- data access to a dynamic library goes via a symbol pointer- | labelDynamic config this_mod lbl+ | labelDynamic config lbl = AccessViaSymbolPtr -- when generating PIC code, all cross-module data references must@@ -276,21 +271,21 @@ | otherwise = AccessDirectly -howToAccessLabel config arch OSDarwin this_mod JumpReference lbl+howToAccessLabel config arch OSDarwin JumpReference lbl -- dyld code stubs don't work for tailcalls because the -- stack alignment is only right for regular calls. -- Therefore, we have to go via a symbol pointer: | arch == ArchX86 || arch == ArchX86_64- , labelDynamic config this_mod lbl+ , labelDynamic config lbl = AccessViaSymbolPtr -howToAccessLabel config arch OSDarwin this_mod _ lbl+howToAccessLabel config arch OSDarwin _kind lbl -- Code stubs are the usual method of choice for imported code; -- not needed on x86_64 because Apple's new linker, ld64, generates -- them automatically. | arch /= ArchX86_64- , labelDynamic config this_mod lbl+ , labelDynamic config lbl = AccessViaStub | otherwise@@ -301,7 +296,7 @@ -- AIX -- quite simple (for now)-howToAccessLabel _config _arch OSAIX _this_mod kind _lbl+howToAccessLabel _config _arch OSAIX kind _lbl = case kind of DataReference -> AccessViaSymbolPtr CallReference -> AccessDirectly@@ -318,7 +313,7 @@ -- from position independent code. It is also required from the main program -- when dynamic libraries containing Haskell code are used. -howToAccessLabel _ (ArchPPC_64 _) os _ kind _+howToAccessLabel _config (ArchPPC_64 _) os kind _lbl | osElfTarget os = case kind of -- ELF PPC64 (powerpc64-linux), AIX, MacOS 9, BeOS/PPC@@ -330,7 +325,7 @@ -- regular calls are handled by the runtime linker _ -> AccessDirectly -howToAccessLabel config _ os _ _ _+howToAccessLabel config _arch os _kind _lbl -- no PIC -> the dynamic linker does everything for us; -- if we don't dynamically link to Haskell code, -- it actually manages to do so without messing things up.@@ -339,11 +334,11 @@ not (ncgExternalDynamicRefs config) = AccessDirectly -howToAccessLabel config arch os this_mod DataReference lbl+howToAccessLabel config arch os DataReference lbl | osElfTarget os = case () of -- A dynamic label needs to be accessed via a symbol pointer.- _ | labelDynamic config this_mod lbl+ _ | labelDynamic config lbl -> AccessViaSymbolPtr -- For PowerPC32 -fPIC, we have to access even static data@@ -369,25 +364,25 @@ -- (AccessDirectly, because we get an implicit symbol stub) -- and calling functions from PIC code on non-i386 platforms (via a symbol stub) -howToAccessLabel config arch os this_mod CallReference lbl+howToAccessLabel config arch os CallReference lbl | osElfTarget os- , labelDynamic config this_mod lbl && not (ncgPIC config)+ , labelDynamic config lbl && not (ncgPIC config) = AccessDirectly | osElfTarget os , arch /= ArchX86- , labelDynamic config this_mod lbl+ , labelDynamic config lbl , ncgPIC config = AccessViaStub -howToAccessLabel config _ os this_mod _ lbl+howToAccessLabel config _arch os _kind lbl | osElfTarget os- = if labelDynamic config this_mod lbl+ = if labelDynamic config lbl then AccessViaSymbolPtr else AccessDirectly -- all other platforms-howToAccessLabel config _ _ _ _ _+howToAccessLabel config _arch _os _kind _lbl | not (ncgPIC config) = AccessDirectly
compiler/GHC/CmmToAsm/Ppr.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE MagicHash #-}+{-# LANGUAGE CPP, MagicHash #-} ----------------------------------------------------------------------------- --@@ -38,9 +38,17 @@ import Data.Bits import Data.ByteString (ByteString) import qualified Data.ByteString as BS-import GHC.Exts+import GHC.Exts hiding (extendWord8#) import GHC.Word +#if MIN_VERSION_base(4,16,0)+import GHC.Base (extendWord8#)+#else+extendWord8# :: Word# -> Word#+extendWord8# w = w+{-# INLINE extendWord8# #-}+#endif+ -- ----------------------------------------------------------------------------- -- Converting floating-point literals to integrals for printing @@ -103,7 +111,7 @@ -- we know that the Chars we create are in the ASCII range -- so we bypass the check in "chr" chr' :: Word8 -> Char- chr' (W8# w#) = C# (chr# (word2Int# w#))+ chr' (W8# w#) = C# (chr# (word2Int# (extendWord8# w#))) octal :: Word8 -> String octal w = [ chr' (ord0 + (w `unsafeShiftR` 6) .&. 0x07)
compiler/GHC/CmmToAsm/Reg/Graph.hs view
@@ -283,7 +283,8 @@ , raCoalesced = rmCoalesce , raSpillStats = spillStats , raSpillCosts = spillCosts- , raSpilled = code_spilled }+ , raSpilled = code_spilled+ , raPlatform = platform } -- Bundle up all the register allocator statistics. -- .. but make sure to drop them on the floor if they're not
compiler/GHC/CmmToAsm/Reg/Graph/Stats.hs view
@@ -79,7 +79,11 @@ , raSpillCosts :: SpillCostInfo -- | Code with spill instructions added.- , raSpilled :: [LiveCmmDecl statics instr] }+ , raSpilled :: [LiveCmmDecl statics instr]++ -- | Target platform+ , raPlatform :: !Platform+ } -- a successful coloring
compiler/GHC/CmmToAsm/Reg/Graph/TrivColorable.hs view
@@ -115,7 +115,7 @@ ArchSPARC64 -> panic "trivColorable ArchSPARC64" ArchPPC_64 _ -> 15 ArchARM _ _ _ -> panic "trivColorable ArchARM"- ArchARM64 -> panic "trivColorable ArchARM64"+ ArchAArch64 -> panic "trivColorable ArchAArch64" ArchAlpha -> panic "trivColorable ArchAlpha" ArchMipseb -> panic "trivColorable ArchMipseb" ArchMipsel -> panic "trivColorable ArchMipsel"@@ -146,7 +146,7 @@ ArchSPARC64 -> panic "trivColorable ArchSPARC64" ArchPPC_64 _ -> 0 ArchARM _ _ _ -> panic "trivColorable ArchARM"- ArchARM64 -> panic "trivColorable ArchARM64"+ ArchAArch64 -> panic "trivColorable ArchAArch64" ArchAlpha -> panic "trivColorable ArchAlpha" ArchMipseb -> panic "trivColorable ArchMipseb" ArchMipsel -> panic "trivColorable ArchMipsel"@@ -179,7 +179,7 @@ ArchSPARC64 -> panic "trivColorable ArchSPARC64" ArchPPC_64 _ -> 20 ArchARM _ _ _ -> panic "trivColorable ArchARM"- ArchARM64 -> panic "trivColorable ArchARM64"+ ArchAArch64 -> panic "trivColorable ArchAArch64" ArchAlpha -> panic "trivColorable ArchAlpha" ArchMipseb -> panic "trivColorable ArchMipseb" ArchMipsel -> panic "trivColorable ArchMipsel"
compiler/GHC/CmmToAsm/Reg/Linear.hs view
@@ -223,7 +223,7 @@ ArchSPARC64 -> panic "linearRegAlloc ArchSPARC64" ArchPPC -> go $ (frInitFreeRegs platform :: PPC.FreeRegs) ArchARM _ _ _ -> panic "linearRegAlloc ArchARM"- ArchARM64 -> panic "linearRegAlloc ArchARM64"+ ArchAArch64 -> panic "linearRegAlloc ArchAArch64" ArchPPC_64 _ -> go $ (frInitFreeRegs platform :: PPC.FreeRegs) ArchAlpha -> panic "linearRegAlloc ArchAlpha" ArchMipseb -> panic "linearRegAlloc ArchMipseb"
compiler/GHC/CmmToAsm/Reg/Linear/FreeRegs.hs view
@@ -78,7 +78,7 @@ ArchSPARC -> SPARC.Instr.maxSpillSlots config ArchSPARC64 -> panic "maxSpillSlots ArchSPARC64" ArchARM _ _ _ -> panic "maxSpillSlots ArchARM"- ArchARM64 -> panic "maxSpillSlots ArchARM64"+ ArchAArch64 -> panic "maxSpillSlots ArchAArch64" ArchPPC_64 _ -> PPC.Instr.maxSpillSlots config ArchAlpha -> panic "maxSpillSlots ArchAlpha" ArchMipseb -> panic "maxSpillSlots ArchMipseb"
compiler/GHC/CmmToAsm/Reg/Target.hs view
@@ -48,7 +48,7 @@ ArchSPARC64 -> panic "targetVirtualRegSqueeze ArchSPARC64" ArchPPC_64 _ -> PPC.virtualRegSqueeze ArchARM _ _ _ -> panic "targetVirtualRegSqueeze ArchARM"- ArchARM64 -> panic "targetVirtualRegSqueeze ArchARM64"+ ArchAArch64 -> panic "targetVirtualRegSqueeze ArchAArch64" ArchAlpha -> panic "targetVirtualRegSqueeze ArchAlpha" ArchMipseb -> panic "targetVirtualRegSqueeze ArchMipseb" ArchMipsel -> panic "targetVirtualRegSqueeze ArchMipsel"@@ -67,7 +67,7 @@ ArchSPARC64 -> panic "targetRealRegSqueeze ArchSPARC64" ArchPPC_64 _ -> PPC.realRegSqueeze ArchARM _ _ _ -> panic "targetRealRegSqueeze ArchARM"- ArchARM64 -> panic "targetRealRegSqueeze ArchARM64"+ ArchAArch64 -> panic "targetRealRegSqueeze ArchAArch64" ArchAlpha -> panic "targetRealRegSqueeze ArchAlpha" ArchMipseb -> panic "targetRealRegSqueeze ArchMipseb" ArchMipsel -> panic "targetRealRegSqueeze ArchMipsel"@@ -85,7 +85,7 @@ ArchSPARC64 -> panic "targetClassOfRealReg ArchSPARC64" ArchPPC_64 _ -> PPC.classOfRealReg ArchARM _ _ _ -> panic "targetClassOfRealReg ArchARM"- ArchARM64 -> panic "targetClassOfRealReg ArchARM64"+ ArchAArch64 -> panic "targetClassOfRealReg ArchAArch64" ArchAlpha -> panic "targetClassOfRealReg ArchAlpha" ArchMipseb -> panic "targetClassOfRealReg ArchMipseb" ArchMipsel -> panic "targetClassOfRealReg ArchMipsel"@@ -103,7 +103,7 @@ ArchSPARC64 -> panic "targetMkVirtualReg ArchSPARC64" ArchPPC_64 _ -> PPC.mkVirtualReg ArchARM _ _ _ -> panic "targetMkVirtualReg ArchARM"- ArchARM64 -> panic "targetMkVirtualReg ArchARM64"+ ArchAArch64 -> panic "targetMkVirtualReg ArchAArch64" ArchAlpha -> panic "targetMkVirtualReg ArchAlpha" ArchMipseb -> panic "targetMkVirtualReg ArchMipseb" ArchMipsel -> panic "targetMkVirtualReg ArchMipsel"@@ -121,7 +121,7 @@ ArchSPARC64 -> panic "targetRegDotColor ArchSPARC64" ArchPPC_64 _ -> PPC.regDotColor ArchARM _ _ _ -> panic "targetRegDotColor ArchARM"- ArchARM64 -> panic "targetRegDotColor ArchARM64"+ ArchAArch64 -> panic "targetRegDotColor ArchAArch64" ArchAlpha -> panic "targetRegDotColor ArchAlpha" ArchMipseb -> panic "targetRegDotColor ArchMipseb" ArchMipsel -> panic "targetRegDotColor ArchMipsel"
compiler/GHC/CmmToAsm/X86/CodeGen.hs view
@@ -1052,7 +1052,9 @@ -------------------- add_code :: Width -> CmmExpr -> CmmExpr -> NatM Register add_code rep x (CmmLit (CmmInt y _))- | is32BitInteger y = add_int rep x y+ | is32BitInteger y+ , rep /= W8 -- LEA doesn't support byte size (#18614)+ = add_int rep x y add_code rep x y = trivialCode rep (ADD format) (Just (ADD format)) x y where format = intFormat rep -- TODO: There are other interesting patterns we want to replace@@ -1061,7 +1063,9 @@ -------------------- sub_code :: Width -> CmmExpr -> CmmExpr -> NatM Register sub_code rep x (CmmLit (CmmInt y _))- | is32BitInteger (-y) = add_int rep x (-y)+ | is32BitInteger (-y)+ , rep /= W8 -- LEA doesn't support byte size (#18614)+ = add_int rep x (-y) sub_code rep x y = trivialCode rep (SUB (intFormat rep)) Nothing x y -- our three-operand add instruction:@@ -1824,7 +1828,36 @@ codes are set according to the supplied comparison operation. -} +{- Note [64-bit integer comparisons on 32-bit]+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + When doing these comparisons there are 2 kinds of+ comparisons.++ * Comparison for equality (or lack thereof)++ We use xor to check if high/low bits are+ equal. Then combine the results using or and+ perform a single conditional jump based on the+ result.++ * Other comparisons:++ We map all other comparisons to the >= operation.+ Why? Because it's easy to encode it with a single+ conditional jump.++ We do this by first computing [r1_lo - r2_lo]+ and use the carry flag to compute+ [r1_high - r2_high - CF].++ At which point if r1 >= r2 then the result will be+ positive. Otherwise negative so we can branch on this+ condition.++-}++ genCondBranch :: BlockId -- the source of the jump -> BlockId -- the true branch target@@ -1841,23 +1874,64 @@ -> NatM InstrBlock -- 64-bit integer comparisons on 32-bit+-- See Note [64-bit integer comparisons on 32-bit] genCondBranch' is32Bit _bid true false (CmmMachOp mop [e1,e2]) | is32Bit, Just W64 <- maybeIntComparison mop = do- ChildCode64 code1 r1_lo <- iselExpr64 e1- ChildCode64 code2 r2_lo <- iselExpr64 e2- let r1_hi = getHiVRegFromLo r1_lo- r2_hi = getHiVRegFromLo r2_lo- cond = machOpToCond mop- Just cond' = maybeFlipCond cond- --TODO: Update CFG for x86- let code = code1 `appOL` code2 `appOL` toOL [- CMP II32 (OpReg r2_hi) (OpReg r1_hi),- JXX cond true,- JXX cond' false,- CMP II32 (OpReg r2_lo) (OpReg r1_lo),- JXX cond true] `appOL` genBranch false- return code + -- The resulting registers here are both the lower part of+ -- the register as well as a way to get at the higher part.+ ChildCode64 code1 r1 <- iselExpr64 e1+ ChildCode64 code2 r2 <- iselExpr64 e2+ let cond = machOpToCond mop :: Cond++ let cmpCode = intComparison cond true false r1 r2+ return $ code1 `appOL` code2 `appOL` cmpCode++ where+ intComparison :: Cond -> BlockId -> BlockId -> Reg -> Reg -> InstrBlock+ intComparison cond true false r1_lo r2_lo =+ case cond of+ -- Impossible results of machOpToCond+ ALWAYS -> panic "impossible"+ NEG -> panic "impossible"+ POS -> panic "impossible"+ CARRY -> panic "impossible"+ OFLO -> panic "impossible"+ PARITY -> panic "impossible"+ NOTPARITY -> panic "impossible"+ -- Special case #1 x == y and x != y+ EQQ -> cmpExact+ NE -> cmpExact+ -- [x >= y]+ GE -> cmpGE+ GEU -> cmpGE+ -- [x > y] <==> ![y >= x]+ GTT -> intComparison GE false true r2_lo r1_lo+ GU -> intComparison GEU false true r2_lo r1_lo+ -- [x <= y] <==> [y >= x]+ LE -> intComparison GE true false r2_lo r1_lo+ LEU -> intComparison GEU true false r2_lo r1_lo+ -- [x < y] <==> ![x >= x]+ LTT -> intComparison GE false true r1_lo r2_lo+ LU -> intComparison GEU false true r1_lo r2_lo+ where+ r1_hi = getHiVRegFromLo r1_lo+ r2_hi = getHiVRegFromLo r2_lo+ cmpExact :: OrdList Instr+ cmpExact =+ toOL+ [ XOR II32 (OpReg r2_hi) (OpReg r1_hi)+ , XOR II32 (OpReg r2_lo) (OpReg r1_lo)+ , OR II32 (OpReg r1_hi) (OpReg r1_lo)+ , JXX cond true+ , JXX ALWAYS false+ ]+ cmpGE = toOL+ [ CMP II32 (OpReg r2_lo) (OpReg r1_lo)+ , SBB II32 (OpReg r2_hi) (OpReg r1_hi)+ , JXX cond true+ , JXX ALWAYS false ]+ genCondBranch' _ bid id false bool = do CondCode is_float cond cond_code <- getCondCode bool use_sse2 <- sse2Enabled@@ -2047,12 +2121,12 @@ -- final move should go away, because it's the last use of arg -- and the first use of dst_r. AMO_Add -> return $ (toOL [ LOCK (XADD format (OpReg arg) (OpAddr amode))- , MOV format (OpReg arg) (OpReg dst_r)- ], bid)+ , MOV format (OpReg arg) (OpReg dst_r)+ ], bid) AMO_Sub -> return $ (toOL [ NEGI format (OpReg arg)- , LOCK (XADD format (OpReg arg) (OpAddr amode))- , MOV format (OpReg arg) (OpReg dst_r)- ], bid)+ , LOCK (XADD format (OpReg arg) (OpAddr amode))+ , MOV format (OpReg arg) (OpReg dst_r)+ ], bid) -- In these cases we need a new block id, and have to return it so -- that later instruction selection can reference it. AMO_And -> cmpxchg_code (\ src dst -> unitOL $ AND format src dst)
compiler/GHC/CmmToAsm/X86/Cond.hs view
@@ -11,22 +11,22 @@ data Cond = ALWAYS -- What's really used? ToDo- | EQQ- | GE- | GEU- | GTT- | GU- | LE- | LEU- | LTT- | LU- | NE- | NEG- | POS- | CARRY- | OFLO- | PARITY- | NOTPARITY+ | EQQ -- je/jz -> zf = 1+ | GE -- jge+ | GEU -- ae+ | GTT -- jg+ | GU -- ja+ | LE -- jle+ | LEU -- jbe+ | LTT -- jl+ | LU -- jb+ | NE -- jne+ | NEG -- js+ | POS -- jns+ | CARRY -- jc+ | OFLO -- jo+ | PARITY -- jp+ | NOTPARITY -- jnp deriving Eq condToUnsigned :: Cond -> Cond
compiler/GHC/CmmToAsm/X86/Ppr.hs view
@@ -90,19 +90,21 @@ -- special case for code without info table: pprSectionAlign config (Section Text lbl) $$ pprProcAlignment config $$+ pprProcLabel config lbl $$ pprLabel platform lbl $$ -- blocks guaranteed not null, so label needed vcat (map (pprBasicBlock config top_info) blocks) $$- (if ncgDwarfEnabled config- then pdoc platform (mkAsmTempEndLabel lbl) <> char ':' else empty) $$+ ppWhen (ncgDwarfEnabled config) (pprBlockEndLabel platform lbl $$ pprProcEndLabel platform lbl) $$ pprSizeDecl platform lbl Just (CmmStaticsRaw info_lbl _) -> pprSectionAlign config (Section Text info_lbl) $$ pprProcAlignment config $$+ pprProcLabel config lbl $$ (if platformHasSubsectionsViaSymbols platform then pdoc platform (mkDeadStripPreventer info_lbl) <> char ':' else empty) $$ vcat (map (pprBasicBlock config top_info) blocks) $$+ ppWhen (ncgDwarfEnabled config) (pprProcEndLabel platform info_lbl) $$ -- above: Even the first block gets a label, because with branch-chain -- elimination, it might be the target of a goto. (if platformHasSubsectionsViaSymbols platform@@ -114,6 +116,25 @@ else empty) $$ pprSizeDecl platform info_lbl +-- | Output an internal proc label. See Note [Internal proc labels] in CLabel.+pprProcLabel :: NCGConfig -> CLabel -> SDoc+pprProcLabel config lbl+ | ncgExposeInternalSymbols config+ , Just lbl' <- ppInternalProcLabel (ncgThisModule config) lbl+ = lbl' <> char ':'+ | otherwise+ = empty++pprProcEndLabel :: Platform -> CLabel -- ^ Procedure name+ -> SDoc+pprProcEndLabel platform lbl =+ pdoc platform (mkAsmTempProcEndLabel lbl) <> char ':'++pprBlockEndLabel :: Platform -> CLabel -- ^ Block name+ -> SDoc+pprBlockEndLabel platform lbl =+ pdoc platform (mkAsmTempEndLabel lbl) <> char ':'+ -- | Output the ELF .size directive. pprSizeDecl :: Platform -> CLabel -> SDoc pprSizeDecl platform lbl@@ -126,9 +147,11 @@ = maybe_infotable $ pprLabel platform asmLbl $$ vcat (map (pprInstr platform) instrs) $$- (if ncgDwarfEnabled config- then pdoc (ncgPlatform config) (mkAsmTempEndLabel asmLbl) <> char ':'- else empty+ ppWhen (ncgDwarfEnabled config) (+ -- Emit both end labels since this may end up being a standalone+ -- top-level block+ pprBlockEndLabel platform asmLbl+ <> pprProcEndLabel platform asmLbl ) where asmLbl = blockLbl blockid@@ -141,10 +164,8 @@ vcat (map (pprData config) info) $$ pprLabel platform infoLbl $$ c $$- (if ncgDwarfEnabled config- then pdoc platform (mkAsmTempEndLabel infoLbl) <> char ':'- else empty- )+ ppWhen (ncgDwarfEnabled config) (pdoc platform (mkAsmTempEndLabel infoLbl) <> char ':')+ -- Make sure the info table has the right .loc for the block -- coming right after it. See [Note: Info Offset] infoTableLoc = case instrs of
compiler/GHC/CmmToC.hs view
@@ -159,8 +159,14 @@ -- See Note [StgWord alignment] , pprAlignment (wordWidth platform) , text "= {" ]- $$ nest 8 (commafy (pprStatics platform ds))+ $$ nest 8 (commafy (staticLitsToWords platform $ toLits ds)) $$ text "};"+ where+ toLits :: [CmmStatic] -> [CmmLit]+ toLits = map f+ where+ f (CmmStaticLit lit) = lit+ f static = pprPanic "pprWordArray: Unexpected literal" (pprStatic platform static) pprAlignment :: Width -> SDoc pprAlignment words =@@ -501,59 +507,69 @@ -- --------------------------------------------------------------------------- -- Static data -pprStatics :: Platform -> [CmmStatic] -> [SDoc]-pprStatics platform = pprStatics'+-- | Produce a list of word sized literals encoding the given list of 'CmmLit's.+staticLitsToWords :: Platform -> [CmmLit] -> [SDoc]+staticLitsToWords platform = go . foldMap decomposeMultiWord where- pprStatics' = \case- [] -> []- (CmmStaticLit (CmmFloat f W32) : rest)- -- odd numbers of floats are padded to a word by mkVirtHeapOffsetsWithPadding- | wordWidth platform == W64, CmmStaticLit (CmmInt 0 W32) : rest' <- rest- -> pprLit1 platform (floatToWord platform f) : pprStatics' rest'- -- adjacent floats aren't padded but combined into a single word- | wordWidth platform == W64, CmmStaticLit (CmmFloat g W32) : rest' <- rest- -> pprLit1 platform (floatPairToWord platform f g) : pprStatics' rest'- | wordWidth platform == W32- -> pprLit1 platform (floatToWord platform f) : pprStatics' rest- | otherwise- -> pprPanic "pprStatics: float" (vcat (map ppr' rest))- where ppr' (CmmStaticLit l) = ppr (cmmLitType platform l)- ppr' _other = text "bad static!"-- (CmmStaticLit (CmmFloat f W64) : rest)- -> map (pprLit1 platform) (doubleToWords platform f) ++ pprStatics' rest+ -- rem_bytes is how many bytes remain in the word we are currently filling.+ -- accum is the word we are filling.+ go :: [CmmLit] -> [SDoc]+ go [] = []+ go lits@(lit : _)+ | Just _ <- isSubWordLit lit+ = goSubWord wordWidthBytes 0 lits+ go (lit : rest)+ = pprLit1 platform lit : go rest - (CmmStaticLit (CmmInt i W64) : rest)- | wordWidth platform == W32- -> case platformByteOrder platform of- BigEndian -> pprStatics' (CmmStaticLit (CmmInt q W32) :- CmmStaticLit (CmmInt r W32) : rest)- LittleEndian -> pprStatics' (CmmStaticLit (CmmInt r W32) :- CmmStaticLit (CmmInt q W32) : rest)- where r = i .&. 0xffffffff- q = i `shiftR` 32+ goSubWord :: Int -> Integer -> [CmmLit] -> [SDoc]+ goSubWord rem_bytes accum (lit : rest)+ | Just (bytes, w) <- isSubWordLit lit+ , rem_bytes >= widthInBytes w+ = let accum' =+ case platformByteOrder platform of+ BigEndian -> (accum `shiftL` widthInBits w) .|. bytes+ LittleEndian -> (accum `shiftL` widthInBits w) .|. byteSwap w bytes+ in goSubWord (rem_bytes - widthInBytes w) accum' rest+ goSubWord rem_bytes accum rest+ = pprWord (byteSwap (wordWidth platform) $ accum `shiftL` (8*rem_bytes)) : go rest - (CmmStaticLit (CmmInt a W32) : CmmStaticLit (CmmInt b W32) : rest)- | wordWidth platform == W64- -> case platformByteOrder platform of- BigEndian -> pprStatics' (CmmStaticLit (CmmInt ((shiftL a 32) .|. b) W64) : rest)- LittleEndian -> pprStatics' (CmmStaticLit (CmmInt ((shiftL b 32) .|. a) W64) : rest)+ -- Decompose multi-word or floating-point literals into multiple+ -- single-word (or smaller) literals.+ decomposeMultiWord :: CmmLit -> [CmmLit]+ decomposeMultiWord (CmmFloat n W64)+ -- This will produce a W64 integer, which will then be broken up further+ -- on the next iteration on 32-bit platforms.+ = [doubleToWord64 n]+ decomposeMultiWord (CmmFloat n W32)+ = [floatToWord32 n]+ decomposeMultiWord (CmmInt n W64)+ | W32 <- wordWidth platform+ = [CmmInt hi W32, CmmInt lo W32]+ where+ hi = n `shiftR` 32+ lo = n .&. 0xffffffff+ decomposeMultiWord lit = [lit] - (CmmStaticLit (CmmInt a W16) : CmmStaticLit (CmmInt b W16) : rest)- | wordWidth platform == W32- -> case platformByteOrder platform of- BigEndian -> pprStatics' (CmmStaticLit (CmmInt ((shiftL a 16) .|. b) W32) : rest)- LittleEndian -> pprStatics' (CmmStaticLit (CmmInt ((shiftL b 16) .|. a) W32) : rest)+ -- Decompose a sub-word-sized literal into the integer value and its+ -- (sub-word-sized) width.+ isSubWordLit :: CmmLit -> Maybe (Integer, Width)+ isSubWordLit lit =+ case lit of+ CmmInt n w+ | w < wordWidth platform -> Just (n, w)+ _ -> Nothing - (CmmStaticLit (CmmInt _ w) : _)- | w /= wordWidth platform- -> pprPanic "pprStatics: cannot emit a non-word-sized static literal" (ppr w)+ wordWidthBytes = widthInBytes $ wordWidth platform - (CmmStaticLit lit : rest)- -> pprLit1 platform lit : pprStatics' rest+ pprWord :: Integer -> SDoc+ pprWord n = pprHexVal platform n (wordWidth platform) - (other : _)- -> pprPanic "pprStatics: other" (pprStatic platform other)+byteSwap :: Width -> Integer -> Integer+byteSwap width n = foldl' f 0 bytes+ where+ f acc m = (acc `shiftL` 8) .|. m+ bytes = [ byte i | i <- [0..widthInBytes width - 1] ]+ byte i = (n `shiftR` (i*8)) .&. 0xff pprStatic :: Platform -> CmmStatic -> SDoc pprStatic platform s = case s of@@ -1158,7 +1174,7 @@ bewareLoadStoreAlignment ArchMipseb = True bewareLoadStoreAlignment ArchMipsel = True bewareLoadStoreAlignment (ArchARM {}) = True- bewareLoadStoreAlignment ArchARM64 = True+ bewareLoadStoreAlignment ArchAArch64 = True bewareLoadStoreAlignment ArchSPARC = True bewareLoadStoreAlignment ArchSPARC64 = True -- Pessimistically assume that they will also cause problems@@ -1252,69 +1268,30 @@ -- This is a hack to turn the floating point numbers into ints that we -- can safely initialise to static locations. -castFloatToWord32Array :: STUArray s Int Float -> ST s (STUArray s Int Word32)-castFloatToWord32Array = U.castSTUArray--castDoubleToWord64Array :: STUArray s Int Double -> ST s (STUArray s Int Word64)-castDoubleToWord64Array = U.castSTUArray--floatToWord :: Platform -> Rational -> CmmLit-floatToWord platform r- = runST (do+floatToWord32 :: Rational -> CmmLit+floatToWord32 r+ = runST $ do arr <- newArray_ ((0::Int),0) writeArray arr 0 (fromRational r) arr' <- castFloatToWord32Array arr w32 <- readArray arr' 0- return (CmmInt (toInteger w32 `shiftL` wo) (wordWidth platform))- )- where wo | wordWidth platform == W64- , BigEndian <- platformByteOrder platform- = 32- | otherwise- = 0--floatPairToWord :: Platform -> Rational -> Rational -> CmmLit-floatPairToWord platform r1 r2- = runST (do- arr <- newArray_ ((0::Int),1)- writeArray arr 0 (fromRational r1)- writeArray arr 1 (fromRational r2)- arr' <- castFloatToWord32Array arr- w32_1 <- readArray arr' 0- w32_2 <- readArray arr' 1- return (pprWord32Pair w32_1 w32_2)- )- where pprWord32Pair w32_1 w32_2- | BigEndian <- platformByteOrder platform =- CmmInt ((shiftL i1 32) .|. i2) W64- | otherwise =- CmmInt ((shiftL i2 32) .|. i1) W64- where i1 = toInteger w32_1- i2 = toInteger w32_2+ return (CmmInt (toInteger w32) W32)+ where+ castFloatToWord32Array :: STUArray s Int Float -> ST s (STUArray s Int Word32)+ castFloatToWord32Array = U.castSTUArray -doubleToWords :: Platform -> Rational -> [CmmLit]-doubleToWords platform r- = runST (do+doubleToWord64 :: Rational -> CmmLit+doubleToWord64 r+ = runST $ do arr <- newArray_ ((0::Int),1) writeArray arr 0 (fromRational r) arr' <- castDoubleToWord64Array arr w64 <- readArray arr' 0- return (pprWord64 w64)- )- where targetWidth = wordWidth platform- pprWord64 w64- | targetWidth == W64 =- [ CmmInt (toInteger w64) targetWidth ]- | targetWidth == W32 =- [ CmmInt (toInteger targetW1) targetWidth- , CmmInt (toInteger targetW2) targetWidth- ]- | otherwise = panic "doubleToWords.pprWord64"- where (targetW1, targetW2) = case platformByteOrder platform of- BigEndian -> (wHi, wLo)- LittleEndian -> (wLo, wHi)- wHi = w64 `shiftR` 32- wLo = w64 .&. 0xFFFFffff+ return $ CmmInt (toInteger w64) W64+ where+ castDoubleToWord64Array :: STUArray s Int Double -> ST s (STUArray s Int Word64)+ castDoubleToWord64Array = U.castSTUArray+ -- --------------------------------------------------------------------------- -- Utils
compiler/GHC/CmmToLlvm/Base.hs view
@@ -476,13 +476,15 @@ ghcInternalFunctions = do platform <- getPlatform let w = llvmWord platform+ cint = LMInt $ widthInBits $ cIntWidth platform+ mk "memcmp" cint [i8Ptr, i8Ptr, w] mk "memcpy" i8Ptr [i8Ptr, i8Ptr, w] mk "memmove" i8Ptr [i8Ptr, i8Ptr, w] mk "memset" i8Ptr [i8Ptr, w, w] mk "newSpark" w [i8Ptr, i8Ptr] where mk n ret args = do- let n' = llvmDefLabel $ fsLit n+ let n' = fsLit n decl = LlvmFunctionDecl n' ExternallyVisible CC_Ccc ret FixedArgs (tysToParams args) Nothing renderLlvm $ ppLlvmFunctionDecl decl@@ -516,7 +518,10 @@ let mkGlbVar lbl ty = LMGlobalVar lbl (LMPointer ty) Private Nothing Nothing case m_ty of -- Directly reference if we have seen it already- Just ty -> return $ mkGlbVar (llvmDefLabel llvmLbl) ty Global+ Just ty -> do+ if llvmLbl `elem` (map fsLit ["newSpark", "memmove", "memcpy", "memcmp", "memset"])+ then return $ mkGlbVar (llvmLbl) ty Global+ else return $ mkGlbVar (llvmDefLabel llvmLbl) ty Global -- Otherwise use a forward alias of it Nothing -> do saveAlias llvmLbl
compiler/GHC/Core/Opt/CprAnal.hs view
@@ -319,7 +319,7 @@ -- See Note [CPR for thunks] stays_thunk = is_thunk && not_strict is_thunk = not (exprIsHNF rhs) && not (isJoinId id)- not_strict = not (isStrictDmd (idDemandInfo id))+ not_strict = not (isStrUsedDmd (idDemandInfo id)) -- See Note [CPR for sum types] (_, ret_ty) = splitPiTys (idType id) not_a_prod = isNothing (deepSplitProductType_maybe (ae_fam_envs env) ret_ty)
compiler/GHC/Core/Opt/DmdAnal.hs view
@@ -44,6 +44,8 @@ import GHC.Builtin.Types.Prim ( realWorldStatePrimTy ) import GHC.Types.Unique.Set +-- import GHC.Driver.Ppr+ {- ************************************************************************ * *@@ -76,12 +78,12 @@ = ( extendAnalEnv TopLevel env id sig , NonRec (setIdStrictness id sig) rhs') where- ( _, sig, rhs') = dmdAnalRhsLetDown Nothing env cleanEvalDmd id rhs+ ( _, sig, rhs') = dmdAnalRhsLetDown Nothing env topSubDmd id rhs dmdAnalTopBind env (Rec pairs) = (env', Rec pairs') where- (env', _, pairs') = dmdFix TopLevel env cleanEvalDmd pairs+ (env', _, pairs') = dmdFix TopLevel env topSubDmd pairs -- We get two iterations automatically -- c.f. the NonRec case above @@ -143,21 +145,20 @@ dmdAnalStar :: AnalEnv -> Demand -- This one takes a *Demand* -> CoreExpr -- Should obey the let/app invariant- -> (BothDmdArg, CoreExpr)-dmdAnalStar env dmd e- | (dmd_shell, cd) <- toCleanDmd dmd- , (dmd_ty, e') <- dmdAnal env cd e+ -> (PlusDmdArg, CoreExpr)+dmdAnalStar env (n :* cd) e+ | (dmd_ty, e') <- dmdAnal env cd e = ASSERT2( not (isUnliftedType (exprType e)) || exprOkForSpeculation e, ppr e ) -- The argument 'e' should satisfy the let/app invariant -- See Note [Analysing with absent demand] in GHC.Types.Demand- (postProcessDmdType dmd_shell dmd_ty, e')+ (toPlusDmdArg $ multDmdType n dmd_ty, e') -- Main Demand Analsysis machinery dmdAnal, dmdAnal' :: AnalEnv- -> CleanDemand -- The main one takes a *CleanDemand*+ -> SubDemand -- The main one takes a *SubDemand* -> CoreExpr -> (DmdType, CoreExpr) --- The CleanDemand is always strict and not absent+-- The SubDemand is always strict and not absent -- See Note [Ensure demand is strict] dmdAnal env d e = -- pprTrace "dmdAnal" (ppr d <+> ppr e) $@@ -172,7 +173,7 @@ = (dmdTransform env var dmd, Var var) dmdAnal' env dmd (Cast e co)- = (dmd_ty `bothDmdType` mkBothDmdArg (coercionDmdEnv co), Cast e' co)+ = (dmd_ty `plusDmdType` mkPlusDmdArg (coercionDmdEnv co), Cast e' co) where (dmd_ty, e') = dmdAnal env dmd e @@ -206,7 +207,7 @@ -- , text "arg dmd_ty =" <+> ppr arg_ty -- , text "res dmd_ty =" <+> ppr res_ty -- , text "overall res dmd_ty =" <+> ppr (res_ty `bothDmdType` arg_ty) ])- (res_ty `bothDmdType` arg_ty, App fun' arg')+ (res_ty `plusDmdType` arg_ty, App fun' arg') dmdAnal' env dmd (Lam var body) | isTyVar var@@ -216,23 +217,35 @@ (body_ty, Lam var body') | otherwise- = let (body_dmd, defer_and_use) = peelCallDmd dmd+ = let (n, body_dmd) = peelCallDmd dmd -- body_dmd: a demand to analyze the body (body_ty, body') = dmdAnal env body_dmd body (lam_ty, var') = annotateLamIdBndr env notArgOfDfun body_ty var in- (postProcessUnsat defer_and_use lam_ty, Lam var' body')+ (multDmdType n lam_ty, Lam var' body') -dmdAnal' env dmd (Case scrut case_bndr ty [(DataAlt dc, bndrs, rhs)])- -- Only one alternative with a product constructor- | let tycon = dataConTyCon dc- , isJust (isDataProductTyCon_maybe tycon)+dmdAnal' env dmd (Case scrut case_bndr ty [(alt, bndrs, rhs)])+ -- Only one alternative.+ -- If it's a DataAlt, it should be a product constructor.+ | is_non_sum_alt alt = let (rhs_ty, rhs') = dmdAnal env dmd rhs (alt_ty1, dmds) = findBndrsDmds env rhs_ty bndrs (alt_ty2, case_bndr_dmd) = findBndrDmd env False alt_ty1 case_bndr- id_dmds = addCaseBndrDmd case_bndr_dmd dmds+ -- Evaluation cardinality on the case binder is irrelevant and a no-op.+ -- What matters is its nested sub-demand!+ (_ :* case_bndr_sd) = case_bndr_dmd+ -- Compute demand on the scrutinee+ (bndrs', scrut_sd)+ | DataAlt _ <- alt+ , id_dmds <- addCaseBndrDmd case_bndr_sd dmds+ -- See Note [Demand on scrutinee of a product case]+ = (setBndrsDemandInfo bndrs id_dmds, mkProd id_dmds)+ | otherwise+ -- __DEFAULT and literal alts. Simply add demands and discard the+ -- evaluation cardinality, as we evaluate the scrutinee exactly once.+ = ASSERT( null bndrs ) (bndrs, case_bndr_sd) fam_envs = ae_fam_envs env alt_ty3 -- See Note [Precise exceptions and strictness analysis] in "GHC.Types.Demand"@@ -241,28 +254,26 @@ | otherwise = alt_ty2 - -- Compute demand on the scrutinee- -- See Note [Demand on scrutinee of a product case]- scrut_dmd = mkProdDmd id_dmds- (scrut_ty, scrut') = dmdAnal env scrut_dmd scrut- res_ty = alt_ty3 `bothDmdType` toBothDmdArg scrut_ty+ (scrut_ty, scrut') = dmdAnal env scrut_sd scrut+ res_ty = alt_ty3 `plusDmdType` toPlusDmdArg scrut_ty case_bndr' = setIdDemandInfo case_bndr case_bndr_dmd- bndrs' = setBndrsDemandInfo bndrs id_dmds in -- pprTrace "dmdAnal:Case1" (vcat [ text "scrut" <+> ppr scrut -- , text "dmd" <+> ppr dmd -- , text "case_bndr_dmd" <+> ppr (idDemandInfo case_bndr')--- , text "id_dmds" <+> ppr id_dmds--- , text "scrut_dmd" <+> ppr scrut_dmd+-- , text "scrut_sd" <+> ppr scrut_sd -- , text "scrut_ty" <+> ppr scrut_ty -- , text "alt_ty" <+> ppr alt_ty2 -- , text "res_ty" <+> ppr res_ty ]) $- (res_ty, Case scrut' case_bndr' ty [(DataAlt dc, bndrs', rhs')])+ (res_ty, Case scrut' case_bndr' ty [(alt, bndrs', rhs')])+ where+ is_non_sum_alt (DataAlt dc) = isJust $ isDataProductTyCon_maybe $ dataConTyCon dc+ is_non_sum_alt _ = True dmdAnal' env dmd (Case scrut case_bndr ty alts) = let -- Case expression with multiple alternatives- (alt_tys, alts') = mapAndUnzip (dmdAnalAlt env dmd case_bndr) alts- (scrut_ty, scrut') = dmdAnal env cleanEvalDmd scrut+ (alt_tys, alts') = mapAndUnzip (dmdAnalSumAlt env dmd case_bndr) alts+ (scrut_ty, scrut') = dmdAnal env topSubDmd scrut (alt_ty, case_bndr') = annotateBndr env (foldr lubDmdType botDmdType alt_tys) case_bndr -- NB: Base case is botDmdType, for empty case alternatives -- This is a unit for lubDmdType, and the right result@@ -274,7 +285,7 @@ = deferAfterPreciseException alt_ty | otherwise = alt_ty- res_ty = alt_ty2 `bothDmdType` toBothDmdArg scrut_ty+ res_ty = alt_ty2 `plusDmdType` toPlusDmdArg scrut_ty in -- pprTrace "dmdAnal:Case2" (vcat [ text "scrut" <+> ppr scrut@@ -304,7 +315,7 @@ id' = setIdDemandInfo id id_dmd (rhs_ty, rhs') = dmdAnalStar env (dmdTransformThunkDmd rhs id_dmd) rhs- final_ty = body_ty' `bothDmdType` rhs_ty+ final_ty = body_ty' `plusDmdType` rhs_ty dmdAnal' env dmd (Let (NonRec id rhs) body) = (body_ty2, Let (NonRec id2 rhs') body')@@ -373,21 +384,77 @@ | otherwise = False -dmdAnalAlt :: AnalEnv -> CleanDemand -> Id -> Alt Var -> (DmdType, Alt Var)-dmdAnalAlt env dmd case_bndr (con,bndrs,rhs)- | null bndrs -- Literals, DEFAULT, and nullary constructors- , (rhs_ty, rhs') <- dmdAnal env dmd rhs- = (rhs_ty, (con, [], rhs'))-- | otherwise -- Non-nullary data constructors- , (rhs_ty, rhs') <- dmdAnal env dmd rhs+dmdAnalSumAlt :: AnalEnv -> SubDemand -> Id -> Alt Var -> (DmdType, Alt Var)+dmdAnalSumAlt env dmd case_bndr (con,bndrs,rhs)+ | (rhs_ty, rhs') <- dmdAnal env dmd rhs , (alt_ty, dmds) <- findBndrsDmds env rhs_ty bndrs- , let case_bndr_dmd = findIdDemand alt_ty case_bndr- id_dmds = addCaseBndrDmd case_bndr_dmd dmds+ , let (_ :* case_bndr_sd) = findIdDemand alt_ty case_bndr+ -- See Note [Demand on scrutinee of a product case]+ id_dmds = addCaseBndrDmd case_bndr_sd dmds = (alt_ty, (con, setBndrsDemandInfo bndrs id_dmds, rhs')) -{- Note [Which scrutinees may throw precise exceptions]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+{-+Note [Analysing with absent demand]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Suppose we analyse an expression with demand A. The "A" means+"absent", so this expression will never be needed. What should happen?+There are several wrinkles:++* We *do* want to analyse the expression regardless.+ Reason: Note [Always analyse in virgin pass]++ But we can post-process the results to ignore all the usage+ demands coming back. This is done by multDmdType.++* In a previous incarnation of GHC we needed to be extra careful in the+ case of an *unlifted type*, because unlifted values are evaluated+ even if they are not used. Example (see #9254):+ f :: (() -> (# Int#, () #)) -> ()+ -- Strictness signature is+ -- <CS(S(A,SU))>+ -- I.e. calls k, but discards first component of result+ f k = case k () of (# _, r #) -> r++ g :: Int -> ()+ g y = f (\n -> (# case y of I# y2 -> y2, n #))++ Here f's strictness signature says (correctly) that it calls its+ argument function and ignores the first component of its result.+ This is correct in the sense that it'd be fine to (say) modify the+ function so that always returned 0# in the first component.++ But in function g, we *will* evaluate the 'case y of ...', because+ it has type Int#. So 'y' will be evaluated. So we must record this+ usage of 'y', else 'g' will say 'y' is absent, and will w/w so that+ 'y' is bound to an aBSENT_ERROR thunk.++ However, the argument of toSubDmd always satisfies the let/app+ invariant; so if it is unlifted it is also okForSpeculation, and so+ can be evaluated in a short finite time -- and that rules out nasty+ cases like the one above. (I'm not quite sure why this was a+ problem in an earlier version of GHC, but it isn't now.)++Note [Always analyse in virgin pass]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Tricky point: make sure that we analyse in the 'virgin' pass. Consider+ rec { f acc x True = f (...rec { g y = ...g... }...)+ f acc x False = acc }+In the virgin pass for 'f' we'll give 'f' a very strict (bottom) type.+That might mean that we analyse the sub-expression containing the+E = "...rec g..." stuff in a bottom demand. Suppose we *didn't analyse*+E, but just returned botType.++Then in the *next* (non-virgin) iteration for 'f', we might analyse E+in a weaker demand, and that will trigger doing a fixpoint iteration+for g. But *because it's not the virgin pass* we won't start g's+iteration at bottom. Disaster. (This happened in $sfibToList' of+nofib/spectral/fibheaps.)++So in the virgin pass we make sure that we do analyse the expression+at least once, to initialise its signatures.++Note [Which scrutinees may throw precise exceptions]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This is the specification of 'exprMayThrowPreciseExceptions', which is important for Scenario 2 of Note [Precise exceptions and strictness analysis] in GHC.Types.Demand.@@ -438,6 +505,9 @@ Note [Aggregated demand for cardinality] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+FIXME: This Note should be named [LetUp vs. LetDown] and probably predates+said separation. SG+ We use different strategies for strictness and usage/cardinality to "unleash" demands captured on free variables by bindings. Let us consider the example:@@ -484,13 +554,14 @@ ************************************************************************ -} -dmdTransform :: AnalEnv -- The strictness environment- -> Id -- The function- -> CleanDemand -- The demand on the function- -> DmdType -- The demand type of the function in this context- -- Returned DmdEnv includes the demand on- -- this function plus demand on its free variables+dmdTransform :: AnalEnv -- ^ The strictness environment+ -> Id -- ^ The function+ -> SubDemand -- ^ The demand on the function+ -> DmdType -- ^ The demand type of the function in this context+ -- Returned DmdEnv includes the demand on+ -- this function plus demand on its free variables +-- See Note [What are demand signatures?] in "GHC.Types.Demand" dmdTransform env var dmd -- Data constructors | isDataConWorkId var@@ -499,7 +570,8 @@ -- Used to be controlled by a flag. -- See #18429 for some perf measurements. | Just _ <- isClassOpId_maybe var- = dmdTransformDictSelSig (idStrictness var) dmd+ = -- pprTrace "dmdTransform:DictSel" (ppr var $$ ppr dmd) $+ dmdTransformDictSelSig (idStrictness var) dmd -- Imported functions | isGlobalId var , let res = dmdTransformSig (idStrictness var) dmd@@ -512,14 +584,14 @@ = -- pprTrace "dmdTransform:LetDown" (vcat [ppr var, ppr sig, ppr dmd, ppr fn_ty]) $ if isTopLevel top_lvl then fn_ty -- Don't record demand on top-level things- else addVarDmd fn_ty var (mkOnceUsedDmd dmd)+ else addVarDmd fn_ty var (C_11 :* dmd) -- Everything else: -- * Local let binders for which we use LetUp (cf. 'useLetUp') -- * Lambda binders -- * Case and constructor field binders | otherwise = -- pprTrace "dmdTransform:other" (vcat [ppr var, ppr sig, ppr dmd, ppr res]) $- unitDmdType (unitVarEnv var (mkOnceUsedDmd dmd))+ unitDmdType (unitVarEnv var (C_11 :* dmd)) {- ********************************************************************* * *@@ -541,14 +613,15 @@ -- This is the LetDown rule in the paper “Higher-Order Cardinality Analysis”. dmdAnalRhsLetDown :: Maybe [Id] -- Just bs <=> recursive, Nothing <=> non-recursive- -> AnalEnv -> CleanDemand+ -> AnalEnv -> SubDemand -> Id -> CoreExpr -> (DmdEnv, StrictSig, CoreExpr) -- Process the RHS of the binding, add the strictness signature -- to the Id, and augment the environment with the signature as well. -- See Note [NOINLINE and strictness] dmdAnalRhsLetDown rec_flag env let_dmd id rhs- = (lazy_fv, sig, rhs')+ = -- pprTrace "dmdAnalRhsLetDown" (ppr id $$ ppr let_dmd $$ ppr sig $$ ppr lazy_fv) $+ (lazy_fv, sig, rhs') where rhs_arity = idArity id rhs_dmd -- See Note [Demand analysis for join points]@@ -567,32 +640,41 @@ sig = mkStrictSigForArity rhs_arity (DmdType sig_fv rhs_dmds rhs_div) -- See Note [Aggregated demand for cardinality]+ -- FIXME: That Note doesn't explain the following lines at all. The reason+ -- is really much different: When we have a recursive function, we'd+ -- have to also consider the free vars of the strictness signature+ -- when checking whether we found a fixed-point. That is expensive;+ -- we only want to check whether argument demands of the sig changed.+ -- reuseEnv makes it so that the FV results are stable as long as the+ -- last argument demands were. Strictness won't change. But used-once+ -- might turn into used-many even if the signature was stable and+ -- we'd have to do an additional iteration. reuseEnv makes sure that+ -- we never get used-once info for FVs of recursive functions. rhs_fv1 = case rec_flag of Just bs -> reuseEnv (delVarEnvList rhs_fv bs) Nothing -> rhs_fv rhs_fv2 = rhs_fv1 `keepAliveDmdEnv` extra_fvs-- -- See Note [Lazy and unleashable free variables]- (lazy_fv, sig_fv) = partitionVarEnv isWeakDmd rhs_fv2- -- Find the RHS free vars of the unfoldings and RULES -- See Note [Absence analysis for stable unfoldings and RULES] extra_fvs = foldr (unionVarSet . ruleRhsFreeIds) unf_fvs $ idCoreRules id + -- See Note [Lazy and unleashable free variables]+ (lazy_fv, sig_fv) = partitionVarEnv isWeakDmd rhs_fv2+ unf = realIdUnfolding id unf_fvs | isStableUnfolding unf , Just unf_body <- maybeUnfoldingTemplate unf = exprFreeIds unf_body | otherwise = emptyVarSet --- | @mkRhsDmd env rhs_arity rhs@ creates a 'CleanDemand' for+-- | @mkRhsDmd env rhs_arity rhs@ creates a 'SubDemand' for -- unleashing on the given function's @rhs@, by creating -- a call demand of @rhs_arity@ -- See Historical Note [Product demands for function body]-mkRhsDmd :: AnalEnv -> Arity -> CoreExpr -> CleanDemand-mkRhsDmd _env rhs_arity _rhs = mkCallDmds rhs_arity cleanEvalDmd+mkRhsDmd :: AnalEnv -> Arity -> CoreExpr -> SubDemand+mkRhsDmd _env rhs_arity _rhs = mkCallDmds rhs_arity topSubDmd -- | If given the (local, non-recursive) let-bound 'Id', 'useLetUp' determines -- whether we should process the binding up (body before rhs) or down (rhs@@ -694,12 +776,14 @@ is /at least/ the number of manifest lambdas, but might be higher for PAPs and trivial RHS (see Note [Demand analysis for trivial right-hand sides]). -Because idArity of a function varies independently of its cardinality properties-(cf. Note [idArity varies independently of dmdTypeDepth]), we implicitly encode-the arity for when a demand signature is sound to unleash in its 'dmdTypeDepth'-(cf. Note [Understanding DmdType and StrictSig] in GHC.Types.Demand). It is unsound to-unleash a demand signature when the incoming number of arguments is less than-that. See Note [What are demand signatures?] for more details on soundness.+Because idArity of a function varies independently of its cardinality+properties (cf. Note [idArity varies independently of dmdTypeDepth]), we+implicitly encode the arity for when a demand signature is sound to unleash+in its 'dmdTypeDepth' (cf. Note [Understanding DmdType and StrictSig] in+GHC.Types.Demand). It is unsound to unleash a demand signature when the+incoming number of arguments is less than that.+See Note [What are demand signatures?] in GHC.Types.Demand for more details+on soundness. Why idArity arguments? Because that's a conservative estimate of how many arguments we must feed a function before it does anything interesting with them.@@ -759,57 +843,6 @@ With the CoreLint check, we would have to zap `go`'s perfectly viable strictness signature. -Note [What are demand signatures?]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Demand analysis interprets expressions in the abstract domain of demand-transformers. Given an incoming demand we put an expression under, its abstract-transformer gives us back a demand type denoting how other things (like-arguments and free vars) were used when the expression was evaluated.-Here's an example:-- f x y =- if x + expensive- then \z -> z + y * ...- else \z -> z * ...--The abstract transformer (let's call it F_e) of the if expression (let's call it-e) would transform an incoming head demand <S,HU> into a demand type like-{x-><S,1*U>,y-><L,U>}<L,U>. In pictures:-- Demand ---F_e---> DmdType- <S,HU> {x-><S,1*U>,y-><L,U>}<L,U>--Let's assume that the demand transformers we compute for an expression are-correct wrt. to some concrete semantics for Core. How do demand signatures fit-in? They are strange beasts, given that they come with strict rules when to-it's sound to unleash them.--Fortunately, we can formalise the rules with Galois connections. Consider-f's strictness signature, {}<S,1*U><L,U>. It's a single-point approximation of-the actual abstract transformer of f's RHS for arity 2. So, what happens is that-we abstract *once more* from the abstract domain we already are in, replacing-the incoming Demand by a simple lattice with two elements denoting incoming-arity: A_2 = {<2, >=2} (where '<2' is the top element and >=2 the bottom-element). Here's the diagram:-- A_2 -----f_f----> DmdType- ^ |- | α γ |- | v- Demand ---F_f---> DmdType--With- α(C1(C1(_))) = >=2 -- example for usage demands, but similar for strictness- α(_) = <2- γ(ty) = ty-and F_f being the abstract transformer of f's RHS and f_f being the abstracted-abstract transformer computable from our demand signature simply by-- f_f(>=2) = {}<S,1*U><L,U>- f_f(<2) = postProcessUnsat {}<S,1*U><L,U>--where postProcessUnsat makes a proper top element out of the given demand type.- Note [Demand analysis for trivial right-hand sides] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider@@ -899,7 +932,7 @@ -- Recursive bindings dmdFix :: TopLevelFlag -> AnalEnv -- Does not include bindings for this binding- -> CleanDemand+ -> SubDemand -> [(Id,CoreExpr)] -> (AnalEnv, DmdEnv, [(Id,CoreExpr)]) -- Binders annotated with strictness info @@ -954,10 +987,11 @@ -- so this can significantly reduce the number of iterations needed my_downRhs (env, lazy_fv) (id,rhs)- = ((env', lazy_fv'), (id', rhs'))+ = -- pprTrace "my_downRhs" (ppr id $$ ppr (idStrictness id) $$ ppr sig) $+ ((env', lazy_fv'), (id', rhs')) where (lazy_fv1, sig, rhs') = dmdAnalRhsLetDown (Just bndrs) env let_dmd id rhs- lazy_fv' = plusVarEnv_C bothDmd lazy_fv lazy_fv1+ lazy_fv' = plusVarEnv_C plusDmd lazy_fv lazy_fv1 env' = extendAnalEnv top_lvl env id sig id' = setIdStrictness id sig @@ -1043,11 +1077,11 @@ addVarDmd :: DmdType -> Var -> Demand -> DmdType addVarDmd (DmdType fv ds res) var dmd- = DmdType (extendVarEnv_C bothDmd fv var dmd) ds res+ = DmdType (extendVarEnv_C plusDmd fv var dmd) ds res addLazyFVs :: DmdType -> DmdEnv -> DmdType addLazyFVs dmd_ty lazy_fvs- = dmd_ty `bothDmdType` mkBothDmdArg lazy_fvs+ = dmd_ty `plusDmdType` mkPlusDmdArg lazy_fvs -- Using bothDmdType (rather than just both'ing the envs) -- is vital. Consider -- let f = \x -> (x,y)@@ -1109,13 +1143,13 @@ -- For lambdas we add the demand to the argument demands -- Only called for Ids = ASSERT( isId id )- -- pprTrace "annLamBndr" (vcat [ppr id, ppr _dmd_ty]) $+ -- pprTrace "annLamBndr" (vcat [ppr id, ppr dmd_ty, ppr final_ty]) $ (final_ty, setIdDemandInfo id dmd) where -- Watch out! See note [Lambda-bound unfoldings] final_ty = case maybeUnfoldingTemplate (idUnfolding id) of Nothing -> main_ty- Just unf -> main_ty `bothDmdType` unf_ty+ Just unf -> main_ty `plusDmdType` unf_ty where (unf_ty, _) = dmdAnalStar env dmd unf @@ -1314,7 +1348,8 @@ findBndrDmd :: AnalEnv -> Bool -> DmdType -> Id -> (DmdType, Demand) -- See Note [Trimming a demand to a type] findBndrDmd env arg_of_dfun dmd_ty id- = (dmd_ty', dmd')+ = -- pprTrace "findBndrDmd" (ppr id $$ ppr dmd_ty $$ ppr starting_dmd $$ ppr dmd') $+ (dmd_ty', dmd') where dmd' = strictify $ trimToType starting_dmd (findTypeShape fam_envs id_ty)
compiler/GHC/Core/Opt/Pipeline.hs view
@@ -16,6 +16,7 @@ import GHC.Driver.Ppr import GHC.Driver.Plugins ( withPlugins, installCoreToDos ) import GHC.Driver.Env+import GHC.Platform.Ways ( hasWay, Way(WayProf) ) import GHC.Core import GHC.Core.Opt.CSE ( cseProgram )@@ -44,6 +45,7 @@ import GHC.Core.Opt.CallArity ( callArityAnalProgram ) import GHC.Core.Opt.Exitify ( exitifyProgram ) import GHC.Core.Opt.WorkWrap ( wwTopBinds )+import GHC.Core.Opt.CallerCC ( addCallerCostCentres ) import GHC.Core.Seq (seqBinds) import GHC.Core.FamInstEnv @@ -58,7 +60,6 @@ import GHC.Unit.Module.ModGuts import GHC.Unit.Module.Deps -import GHC.Runtime.Loader -- ( initializePlugins ) import GHC.Runtime.Context import GHC.Types.SrcLoc@@ -67,7 +68,6 @@ import GHC.Types.Basic import GHC.Types.Var.Set import GHC.Types.Var.Env-import GHC.Types.Demand import GHC.Types.Unique.Supply ( UniqSupply, mkSplitUniqSupply, splitUniqSupply ) import GHC.Types.Unique.FM import GHC.Types.Name.Ppr@@ -87,18 +87,14 @@ , mg_loc = loc , mg_deps = deps , mg_rdr_env = rdr_env })- = do { -- make sure all plugins are loaded-- ; let builtin_passes = getCoreToDo dflags+ = do { let builtin_passes = getCoreToDo dflags orph_mods = mkModuleSet (mod : dep_orphs deps) uniq_mask = 's' ; ; (guts2, stats) <- runCoreM hsc_env hpt_rule_base uniq_mask mod orph_mods print_unqual loc $ do { hsc_env' <- getHscEnv- ; dflags' <- liftIO $ initializePlugins hsc_env'- (hsc_dflags hsc_env')- ; all_passes <- withPlugins dflags'+ ; all_passes <- withPlugins hsc_env' installCoreToDos builtin_passes ; runCorePasses all_passes guts }@@ -156,6 +152,7 @@ pre_inline_on = gopt Opt_SimplPreInlining dflags ww_on = gopt Opt_WorkerWrapper dflags static_ptrs = xopt LangExt.StaticPointers dflags+ profiling = ways dflags `hasWay` WayProf maybe_rule_check phase = runMaybe rule_check (CoreDoRuleCheck phase) @@ -222,12 +219,16 @@ } ] + add_caller_ccs =+ runWhen (profiling && not (null $ callerCcFilters dflags)) CoreAddCallerCcs+ core_todo = if opt_level == 0 then [ static_ptrs_float_outwards, CoreDoSimplify max_iter (base_mode { sm_phase = FinalPhase , sm_names = ["Non-opt simplification"] })+ , add_caller_ccs ] else {- opt_level >= 1 -} [@@ -371,7 +372,9 @@ -- can become /exponentially/ more expensive. See #11731, #12996. runWhen (strictness || late_dmd_anal) CoreDoDemand, - maybe_rule_check FinalPhase+ maybe_rule_check FinalPhase,++ add_caller_ccs ] -- Remove 'CoreDoNothing' and flatten 'CoreDoPasses' for clarity.@@ -510,6 +513,9 @@ doCorePass CoreDoSpecConstr = {-# SCC "SpecConstr" #-} specConstrProgram +doCorePass CoreAddCallerCcs = {-# SCC "AddCallerCcs" #-}+ addCallerCostCentres+ doCorePass CoreDoPrintCore = observe printCore doCorePass (CoreDoRuleCheck phase pat) = ruleCheckPass phase pat doCorePass CoreDoNothing = return@@ -1096,6 +1102,6 @@ } binds_plus_dmds = dmdAnalProgram opts fam_envs binds Err.dumpIfSet_dyn dflags Opt_D_dump_str_signatures "Strictness signatures" FormatText $- dumpIdInfoOfProgram (pprIfaceStrictSig . strictnessInfo) binds_plus_dmds+ dumpIdInfoOfProgram (ppr . strictnessInfo) binds_plus_dmds -- See Note [Stamp out space leaks in demand analysis] in GHC.Core.Opt.DmdAnal seqBinds binds_plus_dmds `seq` return binds_plus_dmds
compiler/GHC/Core/Opt/SetLevels.hs view
@@ -103,7 +103,7 @@ import GHC.Types.Unique.DSet ( getUniqDSet ) import GHC.Types.Var.Env import GHC.Types.Literal ( litIsTrivial )-import GHC.Types.Demand ( StrictSig, Demand, isStrictDmd, splitStrictSig, prependArgsStrictSig )+import GHC.Types.Demand ( StrictSig, Demand, isStrUsedDmd, splitStrictSig, prependArgsStrictSig ) import GHC.Types.Cpr ( mkCprSig, botCpr ) import GHC.Types.Name ( getOccName, mkSystemVarName ) import GHC.Types.Name.Occurrence ( occNameString )@@ -469,7 +469,7 @@ lvl_arg :: [Demand] -> CoreExprWithFVs -> LvlM ([Demand], LevelledExpr) lvl_arg strs arg | (str1 : strs') <- strs , is_val_arg arg- = do { arg' <- lvlMFE env (isStrictDmd str1) arg+ = do { arg' <- lvlMFE env (isStrUsedDmd str1) arg ; return (strs', arg') } | otherwise = do { arg' <- lvlMFE env False arg
compiler/GHC/Core/Opt/Simplify.hs view
@@ -41,15 +41,15 @@ import GHC.Core import GHC.Builtin.Types.Prim( realWorldStatePrimTy ) import GHC.Builtin.Names( runRWKey )-import GHC.Types.Demand ( StrictSig(..), Demand, dmdTypeDepth, isStrictDmd- , mkClosedStrictSig, topDmd, seqDmd, botDiv )+import GHC.Types.Demand ( StrictSig(..), Demand, dmdTypeDepth, isStrUsedDmd+ , mkClosedStrictSig, topDmd, seqDmd, isDeadEndDiv ) import GHC.Types.Cpr ( mkCprSig, botCpr ) import GHC.Core.Ppr ( pprCoreExpr ) import GHC.Types.Unique ( hasKey ) import GHC.Core.Unfold import GHC.Core.Unfold.Make import GHC.Core.Utils-import GHC.Core.Opt.Arity ( ArityType(..), arityTypeArity, isBotArityType+import GHC.Core.Opt.Arity ( ArityType(..) , pushCoTyArg, pushCoValArg , idArityType, etaExpandAT ) import GHC.Core.SimpleOpt ( exprIsConApp_maybe, joinPointBinding_maybe, joinPointBindings_maybe )@@ -796,8 +796,8 @@ addLetBndrInfo new_bndr new_arity_type new_unf = new_bndr `setIdInfo` info5 where- new_arity = arityTypeArity new_arity_type- is_bot = isBotArityType new_arity_type+ AT oss div = new_arity_type+ new_arity = length oss info1 = idInfo new_bndr `setArityInfo` new_arity @@ -816,11 +816,11 @@ = info2 -- Bottoming bindings: see Note [Bottoming bindings]- info4 | is_bot = info3 `setStrictnessInfo` bot_sig- `setCprInfo` bot_cpr- | otherwise = info3+ info4 | isDeadEndDiv div = info3 `setStrictnessInfo` bot_sig+ `setCprInfo` bot_cpr+ | otherwise = info3 - bot_sig = mkClosedStrictSig (replicate new_arity topDmd) botDiv+ bot_sig = mkClosedStrictSig (replicate new_arity topDmd) div bot_cpr = mkCprSig new_arity botCpr -- Zap call arity info. We have used it by now (via@@ -2481,7 +2481,7 @@ scrut_is_demanded_var :: CoreExpr -> Bool scrut_is_demanded_var (Cast s _) = scrut_is_demanded_var s- scrut_is_demanded_var (Var _) = isStrictDmd (idDemandInfo case_bndr)+ scrut_is_demanded_var (Var _) = isStrUsedDmd (idDemandInfo case_bndr) scrut_is_demanded_var _ = False This only fired if the scrutinee was a /variable/, which seems@@ -2709,7 +2709,7 @@ | otherwise -- Scrut has a lifted type = exprIsHNF scrut- || isStrictDmd (idDemandInfo case_bndr)+ || isStrUsedDmd (idDemandInfo case_bndr) -- See Note [Case-to-let for strictly-used binders] --------------------------------------------------
compiler/GHC/Core/Opt/Simplify/Utils.hs view
@@ -329,7 +329,7 @@ isStrictArgInfo :: ArgInfo -> Bool -- True if the function is strict in the next argument isStrictArgInfo (ArgInfo { ai_dmds = dmds })- | dmd:_ <- dmds = isStrictDmd dmd+ | dmd:_ <- dmds = isStrUsedDmd dmd | otherwise = False argInfoAppArgs :: [ArgSpec] -> [OutExpr]@@ -576,13 +576,13 @@ add_type_strictness fun_ty dmds | null dmds = [] - | Just (_, fun_ty') <- splitForAllTy_maybe fun_ty+ | Just (_, fun_ty') <- splitForAllTyCoVar_maybe fun_ty = add_type_strictness fun_ty' dmds -- Look through foralls | Just (_, arg_ty, fun_ty') <- splitFunTy_maybe fun_ty -- Add strict-type info , dmd : rest_dmds <- dmds , let dmd' = case isLiftedType_maybe arg_ty of- Just False -> strictenDmd dmd+ Just False -> strictifyDmd dmd _ -> dmd = dmd' : add_type_strictness fun_ty' rest_dmds -- If the type is levity-polymorphic, we can't know whether it's@@ -1662,8 +1662,8 @@ | Just join_arity <- isJoinId_maybe bndr = do { let (join_bndrs, join_body) = collectNBinders join_arity rhs oss = [idOneShotInfo id | id <- join_bndrs, isId id]- arity_type | exprIsDeadEnd join_body = ABot (length oss)- | otherwise = ATop oss+ arity_type | exprIsDeadEnd join_body = mkBotArityType oss+ | otherwise = mkTopArityType oss ; return (arity_type, rhs) } -- Note [Do not eta-expand join points] -- But do return the correct arity and bottom-ness, because
compiler/GHC/Core/Opt/SpecConstr.hs view
@@ -971,7 +971,7 @@ --------------------------------------------------- -- See Note [Forcing specialisation] forceSpecBndr :: ScEnv -> Var -> Bool-forceSpecBndr env var = forceSpecFunTy env . snd . splitForAllTys . varType $ var+forceSpecBndr env var = forceSpecFunTy env . snd . splitForAllTyCoVars . varType $ var forceSpecFunTy :: ScEnv -> Type -> Bool forceSpecFunTy env = any (forceSpecArgTy env) . map scaledThing . fst . splitFunTys@@ -1724,11 +1724,12 @@ go env _ _ = env go_one :: DmdEnv -> Demand -> CoreExpr -> DmdEnv- go_one env d (Var v) = extendVarEnv_C bothDmd env v d- go_one env d e- | Just ds <- splitProdDmd_maybe d -- NB: d does not have to be strict- , (Var _, args) <- collectArgs e = go env ds args- go_one env _ _ = env+ go_one env d (Var v) = extendVarEnv_C plusDmd env v d+ go_one env (_n :* cd) e -- NB: _n does not have to be strict+ | (Var _, args) <- collectArgs e+ , Just ds <- viewProd (length args) cd+ = go env ds args+ go_one env _ _ = env {- Note [spec_usg includes rhs_usg]
compiler/GHC/Core/Opt/WorkWrap/Utils.hs view
@@ -434,7 +434,7 @@ apply_or_bind_then work_fn_args (varToCoreExpr id), res_ty) } - | Just (tv, fun_ty') <- splitForAllTy_maybe fun_ty+ | Just (tv, fun_ty') <- splitForAllTyCoVar_maybe fun_ty = do { uniq <- getUniqueM ; let (subst', tv') = cloneTyVarBndr subst tv uniq -- See Note [Freshen WW arguments]@@ -610,7 +610,7 @@ wantToUnbox fam_envs has_inlineable_prag ty dmd = case deepSplitProductType_maybe fam_envs ty of Just dcac@DataConAppContext{ dcac_arg_tys = con_arg_tys }- | isStrictDmd dmd+ | isStrUsedDmd dmd -- See Note [Unpacking arguments with product and polymorphic demands] , Just cs <- split_prod_dmd_arity dmd (length con_arg_tys) -- See Note [Do not unpack class dictionaries]@@ -621,12 +621,11 @@ _ -> Nothing where split_prod_dmd_arity dmd arty- -- For seqDmd, splitProdDmd_maybe will return Nothing (because how would- -- it know the arity?), but it should behave like <S, U(AAAA)>, for some+ -- For seqDmd, it should behave like <S(AAAA)>, for some -- suitable arity- | isSeqDmd dmd = Just (replicate arty absDmd)- -- Otherwise splitProdDmd_maybe does the job- | otherwise = splitProdDmd_maybe dmd+ | isSeqDmd dmd = Just (replicate arty absDmd)+ | _ :* Prod ds <- dmd = Just ds+ | otherwise = Nothing unbox_one :: DynFlags -> FamInstEnvs -> Var -> [Demand]@@ -1026,7 +1025,7 @@ | Just (tc, tc_args) <- splitTyConApp_maybe ty = go_tc rec_tc tc tc_args - | Just (_, ty') <- splitForAllTy_maybe ty+ | Just (_, ty') <- splitForAllTyCoVar_maybe ty = go rec_tc ty' | otherwise
compiler/GHC/CoreToByteCode.hs view
@@ -403,7 +403,7 @@ p_init = Map.fromList (zip all_args (mkStackOffsets 0 szsb_args)) -- make the arg bitmap- bits = argBits platform (reverse (map bcIdArgRep all_args))+ bits = argBits platform (reverse (map (bcIdArgRep platform) all_args)) bitmap_size = genericLength bits bitmap = mkBitmap platform bits body_code <- schemeER_wrk sum_szsb_args p_init body@@ -508,13 +508,17 @@ -- Delegate tail-calls to schemeT. schemeE d s p e@(AnnApp _ _) = schemeT d s p e -schemeE d s p e@(AnnLit lit) = returnUnboxedAtom d s p e (typeArgRep (literalType lit))+schemeE d s p e@(AnnLit lit) = do+ platform <- profilePlatform <$> getProfile+ returnUnboxedAtom d s p e (typeArgRep platform (literalType lit)) schemeE d s p e@(AnnCoercion {}) = returnUnboxedAtom d s p e V schemeE d s p e@(AnnVar v) -- See Note [Not-necessarily-lifted join points], step 3. | isNNLJoinPoint v = doTailCall d s p (protectNNLJoinPointId v) [AnnVar voidPrimId]- | isUnliftedType (idType v) = returnUnboxedAtom d s p e (bcIdArgRep v)+ | isUnliftedType (idType v) = do+ platform <- profilePlatform <$> getProfile+ returnUnboxedAtom d s p e (bcIdArgRep platform v) | otherwise = schemeT d s p e schemeE d s p (AnnLet (AnnNonRec x (_,rhs)) (_,body))@@ -830,18 +834,19 @@ -- Case 2: Constructor application | Just con <- maybe_saturated_dcon , isUnboxedTupleDataCon con- = case args_r_to_l of- [arg1,arg2] | isVAtom arg1 ->+ = do+ platform <- profilePlatform <$> getProfile+ case args_r_to_l of+ [arg1,arg2] | isVAtom platform arg1 -> unboxedTupleReturn d s p arg2- [arg1,arg2] | isVAtom arg2 ->+ [arg1,arg2] | isVAtom platform arg2 -> unboxedTupleReturn d s p arg1 _other -> multiValException -- Case 3: Ordinary data constructor | Just con <- maybe_saturated_dcon = do alloc_con <- mkConAppCode d s p con args_r_to_l- dflags <- getDynFlags- let platform = targetPlatform dflags+ platform <- profilePlatform <$> getProfile return (alloc_con `appOL` mkSlideW 1 (bytesToWords platform $ d - s) `snocOL` ENTER)@@ -922,7 +927,9 @@ unboxedTupleReturn :: StackDepth -> Sequel -> BCEnv -> AnnExpr' Id DVarSet -> BcM BCInstrList-unboxedTupleReturn d s p arg = returnUnboxedAtom d s p arg (atomRep arg)+unboxedTupleReturn d s p arg = do+ platform <- profilePlatform <$> getProfile+ returnUnboxedAtom d s p arg (atomRep platform arg) -- ----------------------------------------------------------------------------- -- Generate code for a tail-call@@ -934,13 +941,14 @@ -> Id -> [AnnExpr' Id DVarSet] -> BcM BCInstrList-doTailCall init_d s p fn args = do_pushes init_d args (map atomRep args)+doTailCall init_d s p fn args = do+ platform <- profilePlatform <$> getProfile+ do_pushes init_d args (map (atomRep platform) args) where do_pushes !d [] reps = do ASSERT( null reps ) return () (push_fn, sz) <- pushAtom d p (AnnVar fn)- dflags <- getDynFlags- let platform = targetPlatform dflags+ platform <- profilePlatform <$> getProfile ASSERT( sz == wordSize platform ) return () let slide = mkSlideB platform (d - init_d + wordSize platform) (init_d - s) return (push_fn `appOL` (slide `appOL` unitOL ENTER))@@ -948,8 +956,7 @@ let (push_apply, n, rest_of_reps) = findPushSeq reps (these_args, rest_of_args) = splitAt n args (next_d, push_code) <- push_seq d these_args- dflags <- getDynFlags- let platform = targetPlatform dflags+ platform <- profilePlatform <$> getProfile instrs <- do_pushes (next_d + wordSize platform) rest_of_args rest_of_reps -- ^^^ for the PUSH_APPLY_ instruction return (push_code `appOL` (push_apply `consOL` instrs))@@ -1137,8 +1144,8 @@ -- NB: unboxed tuple cases bind the scrut binder to the same offset -- as one of the alt binders, so we have to remove any duplicates here: rel_slots = nub $ map fromIntegral $ concatMap spread binds- spread (id, offset) | isFollowableArg (bcIdArgRep id) = [ rel_offset ]- | otherwise = []+ spread (id, offset) | isFollowableArg (bcIdArgRep platform id) = [ rel_offset ]+ | otherwise = [] where rel_offset = trunc16W $ bytesToWords platform (d - offset) alt_stuff <- mapM codeAlt alts@@ -1157,7 +1164,7 @@ alt_bco' <- emitBc alt_bco let push_alts | isAlgCase = PUSH_ALTS alt_bco'- | otherwise = PUSH_ALTS_UNLIFTED alt_bco' (typeArgRep bndr_ty)+ | otherwise = PUSH_ALTS_UNLIFTED alt_bco' (typeArgRep platform bndr_ty) return (push_alts `consOL` scrut_code) @@ -1374,7 +1381,7 @@ -- slide and return d_after_r_min_s = bytesToWords platform (d_after_r - s) wrapup = mkSlideW (trunc16W r_sizeW) (d_after_r_min_s - r_sizeW)- `snocOL` RETURN_UBX (toArgRep r_rep)+ `snocOL` RETURN_UBX (toArgRep platform r_rep) --trace (show (arg1_offW, args_offW , (map argRepSizeW a_reps) )) $ return ( push_args `appOL`@@ -1387,6 +1394,12 @@ VoidRep -> FFIVoid IntRep -> signed_word WordRep -> unsigned_word+ Int8Rep -> FFISInt8+ Word8Rep -> FFIUInt8+ Int16Rep -> FFISInt16+ Word16Rep -> FFIUInt16+ Int32Rep -> FFISInt32+ Word32Rep -> FFIUInt32 Int64Rep -> FFISInt64 Word64Rep -> FFIUInt64 AddrRep -> FFIPointer@@ -1405,6 +1418,12 @@ = case pr of IntRep -> mkLitInt platform 0 WordRep -> mkLitWord platform 0+ Int8Rep -> mkLitInt8 0+ Word8Rep -> mkLitWord8 0+ Int16Rep -> mkLitInt16 0+ Word16Rep -> mkLitWord16 0+ Int32Rep -> mkLitInt32 0+ Word32Rep -> mkLitWord32 0 Int64Rep -> mkLitInt64 0 Word64Rep -> mkLitWord64 0 AddrRep -> LitNullAddr@@ -1621,24 +1640,39 @@ pushAtom _ _ (AnnLit lit) = do platform <- targetPlatform <$> getDynFlags- let code rep- = let size_words = WordOff (argRepSizeW platform rep)- in return (unitOL (PUSH_UBX lit (trunc16W size_words)),- wordsToBytes platform size_words)+ let code :: PrimRep -> BcM (BCInstrList, ByteOff)+ code rep =+ return (unitOL instr, size_bytes)+ where+ size_bytes = ByteOff $ primRepSizeB platform rep+ -- Here we handle the non-word-width cases specifically since we+ -- must emit different bytecode for them.+ instr =+ case size_bytes of+ 1 -> PUSH_UBX8 lit+ 2 -> PUSH_UBX16 lit+ 4 -> PUSH_UBX32 lit+ _ -> PUSH_UBX lit (trunc16W $ bytesToWords platform size_bytes) case lit of- LitLabel _ _ _ -> code N- LitFloat _ -> code F- LitDouble _ -> code D- LitChar _ -> code N- LitNullAddr -> code N- LitString _ -> code N- LitRubbish -> code N+ LitLabel _ _ _ -> code AddrRep+ LitFloat _ -> code FloatRep+ LitDouble _ -> code DoubleRep+ LitChar _ -> code WordRep+ LitNullAddr -> code AddrRep+ LitString _ -> code AddrRep+ LitRubbish -> code WordRep LitNumber nt _ -> case nt of- LitNumInt -> code N- LitNumWord -> code N- LitNumInt64 -> code L- LitNumWord64 -> code L+ LitNumInt -> code IntRep+ LitNumWord -> code WordRep+ LitNumInt8 -> code Int8Rep+ LitNumWord8 -> code Word8Rep+ LitNumInt16 -> code Int16Rep+ LitNumWord16 -> code Word16Rep+ LitNumInt32 -> code Int32Rep+ LitNumWord32 -> code Word32Rep+ LitNumInt64 -> code Int64Rep+ LitNumWord64 -> code Word64Rep -- No LitInteger's or LitNatural's should be left by the time this is -- called. CorePrep should have converted them all to a real core -- representation.@@ -1827,13 +1861,13 @@ lookupBCEnv_maybe = Map.lookup idSizeW :: Platform -> Id -> WordOff-idSizeW platform = WordOff . argRepSizeW platform . bcIdArgRep+idSizeW platform = WordOff . argRepSizeW platform . bcIdArgRep platform idSizeCon :: Platform -> Id -> ByteOff idSizeCon platform = ByteOff . primRepSizeB platform . bcIdPrimRep -bcIdArgRep :: Id -> ArgRep-bcIdArgRep = toArgRep . bcIdPrimRep+bcIdArgRep :: Platform -> Id -> ArgRep+bcIdArgRep platform = toArgRep platform . bcIdPrimRep bcIdPrimRep :: Id -> PrimRep bcIdPrimRep id@@ -1843,7 +1877,7 @@ = pprPanic "bcIdPrimRep" (ppr id <+> dcolon <+> ppr (idType id)) repSizeWords :: Platform -> PrimRep -> WordOff-repSizeWords platform rep = WordOff $ argRepSizeW platform (toArgRep rep)+repSizeWords platform rep = WordOff $ argRepSizeW platform (toArgRep platform rep) isFollowableArg :: ArgRep -> Bool isFollowableArg P = True@@ -1930,11 +1964,12 @@ Nothing -> e Just e' -> bcViewLoop e' -isVAtom :: AnnExpr' Var ann -> Bool-isVAtom e | Just e' <- bcView e = isVAtom e'-isVAtom (AnnVar v) = isVoidArg (bcIdArgRep v)-isVAtom (AnnCoercion {}) = True-isVAtom _ = False+isVAtom :: Platform -> AnnExpr' Var ann -> Bool+isVAtom platform expr = case expr of+ e | Just e' <- bcView e -> isVAtom platform e'+ (AnnVar v) -> isVoidArg (bcIdArgRep platform v)+ (AnnCoercion {}) -> True+ _ -> False atomPrimRep :: AnnExpr' Id ann -> PrimRep atomPrimRep e | Just e' <- bcView e = atomPrimRep e'@@ -1949,8 +1984,8 @@ atomPrimRep (AnnCoercion {}) = VoidRep atomPrimRep other = pprPanic "atomPrimRep" (ppr (deAnnotate' other)) -atomRep :: AnnExpr' Id ann -> ArgRep-atomRep e = toArgRep (atomPrimRep e)+atomRep :: Platform -> AnnExpr' Id ann -> ArgRep+atomRep platform e = toArgRep platform (atomPrimRep e) -- | Let szsw be the sizes in bytes of some items pushed onto the stack, which -- has initial depth @original_depth@. Return the values which the stack@@ -1958,8 +1993,8 @@ mkStackOffsets :: ByteOff -> [ByteOff] -> [ByteOff] mkStackOffsets original_depth szsb = tail (scanl' (+) original_depth szsb) -typeArgRep :: Type -> ArgRep-typeArgRep = toArgRep . typePrimRep1+typeArgRep :: Platform -> Type -> ArgRep+typeArgRep platform = toArgRep platform . typePrimRep1 -- ----------------------------------------------------------------------------- -- The bytecode generator's monad
compiler/GHC/CoreToStg.hs view
@@ -46,7 +46,7 @@ import GHC.Platform.Ways import GHC.Driver.Ppr import GHC.Types.ForeignCall-import GHC.Types.Demand ( isUsedOnce )+import GHC.Types.Demand ( isUsedOnceDmd ) import GHC.Builtin.PrimOps ( PrimCall(..) ) import GHC.Types.SrcLoc ( mkGeneralSrcSpan ) import GHC.Builtin.Names ( unsafeEqualityProofName )@@ -714,8 +714,8 @@ where unticked_rhs = stripStgTicksTopE (not . tickishIsCode) rhs - upd_flag | isUsedOnce (idDemandInfo bndr) = SingleEntry- | otherwise = Updatable+ upd_flag | isUsedOnceDmd (idDemandInfo bndr) = SingleEntry+ | otherwise = Updatable -- CAF cost centres generated for -fcaf-all caf_cc = mkAutoCC bndr modl@@ -756,8 +756,8 @@ where unticked_rhs = stripStgTicksTopE (not . tickishIsCode) rhs - upd_flag | isUsedOnce (idDemandInfo bndr) = SingleEntry- | otherwise = Updatable+ upd_flag | isUsedOnceDmd (idDemandInfo bndr) = SingleEntry+ | otherwise = Updatable {- SDM: disabled. Eval/Apply can't handle functions with arity zero very
compiler/GHC/CoreToStg/Prep.hs view
@@ -1359,7 +1359,7 @@ -- See Note [Pin demand info on floats] where is_hnf = exprIsHNF rhs- is_strict = isStrictDmd dmd+ is_strict = isStrUsedDmd dmd emptyFloats :: Floats emptyFloats = Floats OkToSpec nilOL@@ -1446,7 +1446,7 @@ wantFloatNested :: RecFlag -> Demand -> Bool -> Floats -> CpeRhs -> Bool wantFloatNested is_rec dmd is_unlifted floats rhs = isEmptyFloats floats- || isStrictDmd dmd+ || isStrUsedDmd dmd || is_unlifted || (allLazyNested is_rec floats && exprIsHNF rhs) -- Why the test for allLazyNested?
compiler/GHC/Driver/Backpack.hs view
@@ -62,7 +62,7 @@ import GHC.Unit.Module.ModSummary (showModMsg) import GHC.Unit.Home.ModInfo -import GHC.Runtime.Linker.Types+import GHC.Linker.Types import qualified GHC.LanguageExtensions as LangExt @@ -204,8 +204,11 @@ hiDir = Just (outdir hiDir), stubDir = Just (outdir stubDir), -- Unset output-file for non exe builds- outputFile = if session_type == ExeSession- then outputFile dflags+ outputFile_ = if session_type == ExeSession+ then outputFile_ dflags+ else Nothing,+ dynOutputFile_ = if session_type == ExeSession+ then dynOutputFile_ dflags else Nothing, -- Clear the import path so we don't accidentally grab anything importPaths = [],
compiler/GHC/Driver/CodeOutput.hs view
@@ -138,7 +138,13 @@ hPutStr h ("/* GHC_PACKAGES " ++ unwords pkg_names ++ "\n*/\n") hPutStr h "#include \"Stg.h\"\n" let platform = targetPlatform dflags- writeC = printForC dflags h . cmmToC platform+ writeC cmm = do+ let doc = cmmToC platform cmm+ dumpIfSet_dyn dflags Opt_D_dump_c_backend+ "C backend output"+ FormatC+ doc+ printForC dflags h doc Stream.consume cmm_stream writeC {-
compiler/GHC/Driver/Main.hs view
@@ -1,6 +1,7 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE BangPatterns #-} {-# LANGUAGE NondecreasingIndentation #-}+{-# LANGUAGE LambdaCase #-} {-# OPTIONS_GHC -fprof-auto-top #-} -------------------------------------------------------------------------------@@ -97,13 +98,14 @@ import GHC.Driver.Hooks import GHC.Runtime.Context-import GHC.Runtime.Linker-import GHC.Runtime.Linker.Types import GHC.Runtime.Interpreter ( addSptEntry ) import GHC.Runtime.Loader ( initializePlugins ) import GHCi.RemoteTypes ( ForeignHValue ) import GHC.ByteCode.Types +import GHC.Linker.Loader+import GHC.Linker.Types+ import GHC.Hs import GHC.Hs.Dump import GHC.Hs.Stats ( ppSourceStats )@@ -238,19 +240,21 @@ us <- mkSplitUniqSupply 'r' nc_var <- newIORef (initNameCache us knownKeyNames) fc_var <- newIORef emptyInstalledModuleEnv- emptyDynLinker <- uninitializedLinker- return HscEnv { hsc_dflags = dflags- , hsc_targets = []- , hsc_mod_graph = emptyMG- , hsc_IC = emptyInteractiveContext dflags- , hsc_HPT = emptyHomePackageTable- , hsc_EPS = eps_var- , hsc_NC = nc_var- , hsc_FC = fc_var- , hsc_type_env_var = Nothing- , hsc_interp = Nothing- , hsc_dynLinker = emptyDynLinker- , hsc_home_unit = home_unit+ emptyLoader <- uninitializedLoader+ return HscEnv { hsc_dflags = dflags+ , hsc_targets = []+ , hsc_mod_graph = emptyMG+ , hsc_IC = emptyInteractiveContext dflags+ , hsc_HPT = emptyHomePackageTable+ , hsc_EPS = eps_var+ , hsc_NC = nc_var+ , hsc_FC = fc_var+ , hsc_type_env_var = Nothing+ , hsc_interp = Nothing+ , hsc_loader = emptyLoader+ , hsc_home_unit = home_unit+ , hsc_plugins = []+ , hsc_static_plugins = [] } -- -----------------------------------------------------------------------------@@ -452,7 +456,8 @@ -- apply parse transformation of plugins let applyPluginAction p opts = parsedResultAction p opts mod_summary- withPlugins dflags applyPluginAction res+ hsc_env <- getHscEnv+ withPlugins hsc_env applyPluginAction res -- -----------------------------------------------------------------------------@@ -762,12 +767,11 @@ -> SourceModified -> Maybe ModIface -> (Int,Int)- -> IO (HscStatus, DynFlags)+ -> IO (HscStatus, HscEnv) hscIncrementalCompile always_do_basic_recompilation_check m_tc_result mHscMessage hsc_env' mod_summary source_modified mb_old_iface mod_index = do- dflags <- initializePlugins hsc_env' (hsc_dflags hsc_env')- let hsc_env'' = hsc_env' { hsc_dflags = dflags }+ hsc_env'' <- initializePlugins hsc_env' -- One-shot mode needs a knot-tying mutable variable for interface -- files. See GHC.Tc.Utils.TcGblEnv.tcg_type_env_var.@@ -802,14 +806,14 @@ -- any further typechecking. It's much more useful -- in make mode, since this HMI will go into the HPT. genModDetails hsc_env' iface- return (HscUpToDate iface details, dflags)+ return (HscUpToDate iface details, hsc_env') -- We finished type checking. (mb_old_hash is the hash of -- the interface that existed on disk; it's possible we had -- to retypecheck but the resulting interface is exactly -- the same.) Right (FrontendTypecheck tc_result, mb_old_hash) -> do status <- finish mod_summary tc_result mb_old_hash- return (status, dflags)+ return (status, hsc_env) -- Runs the post-typechecking frontend (desugar and simplify). We want to -- generate most of the interface as late as possible. This gets us up-to-date@@ -865,8 +869,8 @@ hscs_mod_location = ms_location summary, hscs_mod_details = details, hscs_partial_iface = partial_iface,- hscs_old_iface_hash = mb_old_hash,- hscs_iface_dflags = dflags }+ hscs_old_iface_hash = mb_old_hash+ } -- We are not generating code, so we can skip simplification -- and generate a simple interface.@@ -874,7 +878,7 @@ (iface, mb_old_iface_hash, details) <- liftIO $ hscSimpleIface hsc_env tc_result mb_old_hash - liftIO $ hscMaybeWriteIface dflags iface mb_old_iface_hash (ms_location summary)+ liftIO $ hscMaybeWriteIface dflags True iface mb_old_iface_hash (ms_location summary) return $ case bcknd of NoBackend -> HscNotGeneratingCode iface details@@ -887,28 +891,111 @@ Note [Writing interface files] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We write interface files in GHC.Driver.Main and GHC.Driver.Pipeline using-hscMaybeWriteIface, but only once per compilation (twice with dynamic-too).+We write one interface file per module and per compilation, except with+-dynamic-too where we write two interface files (non-dynamic and dynamic). -* If a compilation does NOT require (re)compilation of the hard code we call- hscMaybeWriteIface inside GHC.Driver.Main:finish.-* If we run in One Shot mode and target bytecode we write it in compileOne'-* Otherwise we must be compiling to regular hard code and require recompilation.- In this case we create the interface file inside RunPhase using the interface- generator contained inside the HscRecomp status.+We can write two kinds of interfaces (see Note [Interface file stages] in+"GHC.Driver.Types"):++ * simple interface: interface generated after the core pipeline++ * full interface: simple interface completed with information from the+ backend++Depending on the situation, we write one or the other (using+`hscMaybeWriteIface`). We must be careful with `-dynamic-too` because only the+backend is run twice, so if we write a simple interface we need to write both+the non-dynamic and the dynamic interfaces at the same time (with the same+contents).++Cases for which we generate simple interfaces:++ * GHC.Driver.Main.finish: when a compilation does NOT require (re)compilation+ of the hard code++ * GHC.Driver.Pipeline.compileOne': when we run in One Shot mode and target+ bytecode (if interface writing is forced).++ * GHC.Driver.Backpack uses simple interfaces for indefinite units+ (units with module holes). It writes them indirectly by forcing the+ -fwrite-interface flag while setting backend to NoBackend.++Cases for which we generate full interfaces:++ * GHC.Driver.Pipeline.runPhase: when we must be compiling to regular hard+ code and/or require recompilation.++By default interface file names are derived from module file names by adding+suffixes. The interface file name can be overloaded with "-ohi", except when+`-dynamic-too` is used.+ -}-hscMaybeWriteIface :: DynFlags -> ModIface -> Maybe Fingerprint -> ModLocation -> IO ()-hscMaybeWriteIface dflags iface old_iface location = do++-- | Write interface files+hscMaybeWriteIface :: DynFlags -> Bool -> ModIface -> Maybe Fingerprint -> ModLocation -> IO ()+hscMaybeWriteIface dflags is_simple iface old_iface mod_location = do let force_write_interface = gopt Opt_WriteInterface dflags write_interface = case backend dflags of NoBackend -> False Interpreter -> False _ -> True- no_change = old_iface == Just (mi_iface_hash (mi_final_exts iface)) - when (write_interface || force_write_interface) $- hscWriteIface dflags iface no_change location+ -- mod_location only contains the base name, so we rebuild the+ -- correct file extension from the dynflags.+ baseName = ml_hi_file mod_location+ buildIfName suffix+ | Just name <- outputHi dflags+ = name+ | otherwise+ = let with_hi = replaceExtension baseName suffix+ in addBootSuffix_maybe (mi_boot iface) with_hi + write_iface dflags' iface =+ {-# SCC "writeIface" #-}+ writeIface dflags' (buildIfName (hiSuf dflags')) iface++ when (write_interface || force_write_interface) $ do++ -- FIXME: with -dynamic-too, "no_change" is only meaningful for the+ -- non-dynamic interface, not for the dynamic one. We should have another+ -- flag for the dynamic interface. In the meantime:+ --+ -- * when we write a single full interface, we check if we are+ -- currently writing the dynamic interface due to -dynamic-too, in+ -- which case we ignore "no_change".+ --+ -- * when we write two simple interfaces at once because of+ -- dynamic-too, we use "no_change" both for the non-dynamic and the+ -- dynamic interfaces. Hopefully both the dynamic and the non-dynamic+ -- interfaces stay in sync...+ --+ let no_change = old_iface == Just (mi_iface_hash (mi_final_exts iface))++ dt <- dynamicTooState dflags++ when (dopt Opt_D_dump_if_trace dflags) $ putMsg dflags $+ hang (text "Writing interface(s):") 2 $ vcat+ [ text "Kind:" <+> if is_simple then text "simple" else text "full"+ , text "Hash change:" <+> ppr (not no_change)+ , text "DynamicToo state:" <+> text (show dt)+ ]++ if is_simple+ then unless no_change $ do -- FIXME: see no_change' comment above+ write_iface dflags iface+ case dt of+ DT_Dont -> return ()+ DT_Failed -> return ()+ DT_Dyn -> panic "Unexpected DT_Dyn state when writing simple interface"+ DT_OK -> write_iface (setDynamicNow dflags) iface+ else case dt of+ DT_Dont | not no_change -> write_iface dflags iface+ DT_OK | not no_change -> write_iface dflags iface+ -- FIXME: see no_change' comment above+ DT_Dyn -> write_iface dflags iface+ DT_Failed | not (dynamicNow dflags) -> write_iface dflags iface+ _ -> return ()+ -------------------------------------------------------------- -- NoRecomp handlers --------------------------------------------------------------@@ -1339,16 +1426,22 @@ -- Simplifiers -------------------------------------------------------------- +-- | Run Core2Core simplifier. The list of String is a list of (Core) plugin+-- module names added via TH (cf 'addCorePlugin'). hscSimplify :: HscEnv -> [String] -> ModGuts -> IO ModGuts hscSimplify hsc_env plugins modguts = runHsc hsc_env $ hscSimplify' plugins modguts +-- | Run Core2Core simplifier. The list of String is a list of (Core) plugin+-- module names added via TH (cf 'addCorePlugin'). hscSimplify' :: [String] -> ModGuts -> Hsc ModGuts hscSimplify' plugins ds_result = do hsc_env <- getHscEnv- let hsc_env_with_plugins = hsc_env- { hsc_dflags = foldr addPluginModuleName (hsc_dflags hsc_env) plugins- }+ hsc_env_with_plugins <- if null plugins -- fast path+ then return hsc_env+ else liftIO $ initializePlugins $ hsc_env+ { hsc_dflags = foldr addPluginModuleName (hsc_dflags hsc_env) plugins+ } {-# SCC "Core2Core" #-} liftIO $ core2core hsc_env_with_plugins ds_result @@ -1383,52 +1476,7 @@ -------------------------------------------------------------- -- BackEnd combinators ---------------------------------------------------------------{--Note [Interface filename extensions]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -ModLocation only contains the base names, however when generating dynamic files-the actual extension might differ from the default.--So we only load the base name from ModLocation and replace the actual extension-according to the information in DynFlags.--If we generate a interface file right after running the core pipeline we will-have set -dynamic-too and potentially generate both interface files at the same-time.--If we generate a interface file after running the backend then dynamic-too won't-be set, however then the extension will be contained in the dynflags instead so-things still work out fine.--}--hscWriteIface :: DynFlags -> ModIface -> Bool -> ModLocation -> IO ()-hscWriteIface dflags iface no_change mod_location = do- -- mod_location only contains the base name, so we rebuild the- -- correct file extension from the dynflags.- let ifaceBaseFile = ml_hi_file mod_location- unless no_change $- let ifaceFile = buildIfName ifaceBaseFile (hiSuf dflags)- in {-# SCC "writeIface" #-}- writeIface dflags ifaceFile iface- whenGeneratingDynamicToo dflags $ do- -- TODO: We should do a no_change check for the dynamic- -- interface file too- -- When we generate iface files after core- let dynDflags = dynamicTooMkDynamicDynFlags dflags- -- dynDflags will have set hiSuf correctly.- dynIfaceFile = buildIfName ifaceBaseFile (hiSuf dynDflags)-- writeIface dynDflags dynIfaceFile iface- where- buildIfName :: String -> String -> String- buildIfName baseName suffix- | Just name <- outputHi dflags- = name- | otherwise- = let with_hi = replaceExtension baseName suffix- in addBootSuffix_maybe (mi_boot iface) with_hi- -- | Compile to hard-code. hscGenHardCode :: HscEnv -> CgGuts -> ModLocation -> FilePath -> IO (FilePath, Maybe FilePath, [(ForeignSrcLang, FilePath)], CgInfos)@@ -1713,7 +1761,7 @@ -- Desugar it ds_expr <- ioMsgMaybe $ deSugarExpr hsc_env tc_expr- liftIO (lintInteractiveExpr "desugar expression" hsc_env ds_expr)+ liftIO (lintInteractiveExpr (text "desugar expression") hsc_env ds_expr) handleWarnings -- Then code-gen, and link it@@ -1799,7 +1847,7 @@ prepd_binds data_tycons mod_breaks let src_span = srcLocSpan interactiveSrcLoc- liftIO $ linkDecls hsc_env src_span cbc+ liftIO $ loadDecls hsc_env src_span cbc {- Load static pointer table entries -} liftIO $ hscAddSptEntries hsc_env (cg_spt_entries tidy_cg)@@ -1831,7 +1879,7 @@ hscAddSptEntries hsc_env entries = do let add_spt_entry :: SptEntry -> IO () add_spt_entry (SptEntry i fpr) = do- val <- getHValue hsc_env (idName i)+ val <- loadName hsc_env (idName i) addSptEntry hsc_env fpr val mapM_ add_spt_entry entries @@ -1955,14 +2003,14 @@ ; prepd_expr <- corePrepExpr hsc_env tidy_expr {- Lint if necessary -}- ; lintInteractiveExpr "hscCompileExpr" hsc_env prepd_expr+ ; lintInteractiveExpr (text "hscCompileExpr") hsc_env prepd_expr {- Convert to BCOs -} ; bcos <- coreExprToBCOs hsc_env (icInteractiveModule (hsc_IC hsc_env)) prepd_expr - {- link it -}- ; linkExpr hsc_env srcspan bcos }+ {- load it -}+ ; loadExpr hsc_env srcspan bcos } {- **********************************************************************
compiler/GHC/Driver/Make.hs view
@@ -36,9 +36,11 @@ import GHC.Prelude import GHC.Tc.Utils.Backpack+import GHC.Tc.Utils.Monad ( initIfaceCheck ) -import qualified GHC.Runtime.Linker as Linker-import GHC.Runtime.Linker.Types+import qualified GHC.Linker.Loader as Linker+import GHC.Linker.Types+ import GHC.Runtime.Context import GHC.Driver.Config@@ -53,9 +55,7 @@ import GHC.Parser.Header import GHC.Parser.Errors.Ppr -import GHC.Utils.Error import GHC.IfaceToCore ( typecheckIface )-import GHC.Tc.Utils.Monad ( initIfaceCheck ) import GHC.Data.Bag ( unitBag, listToBag, unionManyBags, isEmptyBag ) import GHC.Data.Graph.Directed@@ -63,13 +63,14 @@ import GHC.Data.Maybe ( expectJust ) import GHC.Data.StringBuffer import qualified GHC.LanguageExtensions as LangExt-import GHC.SysTools.FileCleanup import GHC.Utils.Exception ( tryIO ) import GHC.Utils.Monad ( allM ) import GHC.Utils.Outputable import GHC.Utils.Panic import GHC.Utils.Misc+import GHC.Utils.Error+import GHC.SysTools.FileCleanup import GHC.Types.Basic import GHC.Types.Target@@ -711,9 +712,9 @@ "must specify -o explicitly" else Just name' in- case outputFile dflags of+ case outputFile_ dflags of Just _ -> env- Nothing -> env { hsc_dflags = dflags { outputFile = name_exe } }+ Nothing -> env { hsc_dflags = dflags { outputFile_ = name_exe } } -- ----------------------------------------------------------------------------- --@@ -2299,8 +2300,8 @@ -- are written into `-odir` and `-hidir` respectively. #16670 if gopt Opt_WriteInterface dflags then return (ml_hi_file ms_location, ml_obj_file ms_location)- else (,) <$> (new_temp_file (hiSuf dflags) (dynHiSuf dflags))- <*> (new_temp_file (objectSuf dflags) (dynObjectSuf dflags))+ else (,) <$> (new_temp_file (hiSuf_ dflags) (dynHiSuf_ dflags))+ <*> (new_temp_file (objectSuf_ dflags) (dynObjectSuf_ dflags)) return $ ms { ms_location =
compiler/GHC/Driver/MakeFile.hs view
@@ -67,11 +67,11 @@ -- We therefore do the initial dependency generation with an empty -- way and .o/.hi extensions, regardless of any flags that might -- be specified.- let dflags = dflags0 {- ways = Set.empty,- hiSuf = "hi",- objectSuf = "o"- }+ let dflags = dflags0+ { targetWays_ = Set.empty+ , hiSuf_ = "hi"+ , objectSuf_ = "o"+ } GHC.setSessionDynFlags dflags when (null (depSuffixes dflags)) $ liftIO $
compiler/GHC/Driver/Pipeline.hs view
@@ -4,6 +4,7 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE NondecreasingIndentation #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE LambdaCase #-} {-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} @@ -20,9 +21,6 @@ -- collection of source files. oneShot, compileFile, - -- Interfaces for the batch-mode driver- linkBinary,- -- Interfaces for the compilation manager (interpreted/batch-mode) preprocess, compileOne, compileOne',@@ -32,8 +30,7 @@ PhasePlus(..), CompPipeline(..), PipeEnv(..), PipeState(..), phaseOutputFilename, getOutputFilename, getPipeState, getPipeEnv, hscPostBackendPhase, getLocation, setModLocation, setDynFlags,- runPhase, exeFileName,- maybeCreateManifest,+ runPhase, doCpp, linkingNeeded, checkLinkInfo, writeInterfaceOnlyMode ) where@@ -64,10 +61,15 @@ import GHC.Parser.Errors.Ppr import GHC.SysTools-import GHC.SysTools.ExtraObj import GHC.SysTools.FileCleanup-import GHC.SysTools.Ar +import GHC.Linker.ExtraObj+import GHC.Linker.Dynamic+import GHC.Linker.MacOS+import GHC.Linker.Unit+import GHC.Linker.Static+import GHC.Linker.Types+ import GHC.Utils.Outputable import GHC.Utils.Error import GHC.Utils.Panic@@ -78,7 +80,6 @@ import GHC.CmmToLlvm ( llvmFixupAsm, llvmVersionList ) import qualified GHC.LanguageExtensions as LangExt import GHC.Settings-import GHC.Runtime.Linker.Types import GHC.Data.Bag ( unitBag ) import GHC.Data.FastString ( mkFastString )@@ -196,10 +197,12 @@ debugTraceMsg dflags1 2 (text "compile: input file" <+> text input_fnpp) -- Run the pipeline up to codeGen (so everything up to, but not including, STG)- (status, plugin_dflags) <- hscIncrementalCompile+ (status, plugin_hsc_env) <- hscIncrementalCompile always_do_basic_recompilation_check m_tc_result mHscMessage hsc_env summary source_modified mb_old_iface (mod_index, nmods)+ -- Use an HscEnv updated with the plugin info+ let hsc_env' = plugin_hsc_env let flags = hsc_dflags hsc_env0 in do unless (gopt Opt_KeepHiFiles flags) $@@ -209,10 +212,6 @@ addFilesToClean flags TFL_GhcSession $ [ml_obj_file $ ms_location summary] - -- Use an HscEnv with DynFlags updated with the plugin info (returned from- -- hscIncrementalCompile)- let hsc_env' = hsc_env{ hsc_dflags = plugin_dflags }- case (status, bcknd) of (HscUpToDate iface hmi_details, _) -> -- TODO recomp014 triggers this assert. What's going on?!@@ -258,12 +257,12 @@ hscs_mod_location = mod_location, hscs_mod_details = hmi_details, hscs_partial_iface = partial_iface,- hscs_old_iface_hash = mb_old_iface_hash,- hscs_iface_dflags = iface_dflags }, Interpreter) -> do+ hscs_old_iface_hash = mb_old_iface_hash+ }, Interpreter) -> do -- In interpreted mode the regular codeGen backend is not run so we -- generate a interface without codeGen info.- final_iface <- mkFullIface hsc_env'{hsc_dflags=iface_dflags} partial_iface Nothing- liftIO $ hscMaybeWriteIface dflags final_iface mb_old_iface_hash (ms_location summary)+ final_iface <- mkFullIface hsc_env' partial_iface Nothing+ liftIO $ hscMaybeWriteIface dflags True final_iface mb_old_iface_hash (ms_location summary) (hasStub, comp_bc, spt_entries) <- hscInteractive hsc_env' cgguts mod_location @@ -549,8 +548,8 @@ let getOfiles (LM _ _ us) = map nameOfObject (filter isObject us) obj_files = concatMap getOfiles linkables-- exe_file = exeFileName staticLink dflags+ platform = targetPlatform dflags+ exe_file = exeFileName platform staticLink (outputFile dflags) linking_needed <- linkingNeeded dflags staticLink linkables pkg_deps @@ -585,7 +584,8 @@ -- if the modification time on the executable is later than the -- modification times on all of the objects and libraries, then omit -- linking (unless the -fforce-recomp flag was given).- let exe_file = exeFileName staticLink dflags+ let platform = targetPlatform dflags+ exe_file = exeFileName platform staticLink (outputFile dflags) e_exe_time <- tryIO $ getModificationUTCTime exe_file case e_exe_time of Left _ -> return True@@ -606,7 +606,7 @@ | Just c <- map (lookupUnitId unit_state) pkg_deps, lib <- packageHsLibs dflags c ] - pkg_libfiles <- mapM (uncurry (findHSLib dflags)) pkg_hslibs+ pkg_libfiles <- mapM (uncurry (findHSLib platform (ways dflags))) pkg_hslibs if any isNothing pkg_libfiles then return True else do e_lib_times <- mapM (tryIO . getModificationUTCTime) (catMaybes pkg_libfiles)@@ -615,11 +615,11 @@ then return True else checkLinkInfo dflags pkg_deps exe_file -findHSLib :: DynFlags -> [String] -> String -> IO (Maybe FilePath)-findHSLib dflags dirs lib = do- let batch_lib_file = if WayDyn `notElem` ways dflags+findHSLib :: Platform -> Ways -> [String] -> String -> IO (Maybe FilePath)+findHSLib platform ws dirs lib = do+ let batch_lib_file = if WayDyn `notElem` ws then "lib" ++ lib <.> "a"- else platformSOName (targetPlatform dflags) lib+ else platformSOName platform lib found <- filterM doesFileExist (map (</> batch_lib_file) dirs) case found of [] -> return Nothing@@ -772,20 +772,41 @@ r <- runPipeline' start_phase hsc_env env input_fn' maybe_loc foreign_os - -- If we are compiling a Haskell module, and doing- -- -dynamic-too, but couldn't do the -dynamic-too fast- -- path, then rerun the pipeline for the dyn way let dflags = hsc_dflags hsc_env- -- NB: Currently disabled on Windows (ref #7134, #8228, and #5987)- when (not $ platformOS (targetPlatform dflags) == OSMinGW32) $- when isHaskellishFile $ whenCannotGenerateDynamicToo dflags $ do- debugTraceMsg dflags 4- (text "Running the pipeline again for -dynamic-too")- let dflags' = dynamicTooMkDynamicDynFlags dflags- hsc_env' <- newHscEnv dflags'- _ <- runPipeline' start_phase hsc_env' env input_fn'- maybe_loc foreign_os- return ()+ when isHaskellishFile $+ dynamicTooState dflags >>= \case+ DT_Dont -> return ()+ DT_Dyn -> return ()+ DT_OK -> return ()+ -- If we are compiling a Haskell module with -dynamic-too, we+ -- first try the "fast path": that is we compile the non-dynamic+ -- version and at the same time we check that interfaces depended+ -- on exist both for the non-dynamic AND the dynamic way. We also+ -- check that they have the same hash.+ -- If they don't, dynamicTooState is set to DT_Failed.+ -- See GHC.Iface.Load.checkBuildDynamicToo+ -- If they do, in the end we produce both the non-dynamic and+ -- dynamic outputs.+ --+ -- If this "fast path" failed, we execute the whole pipeline+ -- again, this time for the dynamic way *only*. To do that we+ -- just set the dynamicNow bit from the start to ensure that the+ -- dynamic DynFlags fields are used and we disable -dynamic-too+ -- (its state is already set to DT_Failed so it wouldn't do much+ -- anyway).+ DT_Failed+ -- NB: Currently disabled on Windows (ref #7134, #8228, and #5987)+ | OSMinGW32 <- platformOS (targetPlatform dflags) -> return ()+ | otherwise -> do+ debugTraceMsg dflags 4+ (text "Running the full pipeline again for -dynamic-too")+ let dflags' = flip gopt_unset Opt_BuildDynamicToo+ $ setDynamicNow+ $ dflags+ hsc_env' <- newHscEnv dflags'+ _ <- runPipeline' start_phase hsc_env' env input_fn'+ maybe_loc foreign_os+ return () return r runPipeline'@@ -849,23 +870,40 @@ _ -> do liftIO $ debugTraceMsg dflags 4 (text "Running phase" <+> ppr phase)- (next_phase, output_fn) <- runHookedPhase phase input_fn dflags+ case phase of HscOut {} -> do- -- We don't pass Opt_BuildDynamicToo to the backend- -- in DynFlags.- -- Instead it's run twice with flags accordingly set- -- per run.- let noDynToo = pipeLoop next_phase output_fn+ let noDynToo = do+ (next_phase, output_fn) <- runHookedPhase phase input_fn dflags+ pipeLoop next_phase output_fn let dynToo = do- setDynFlags $ gopt_unset dflags Opt_BuildDynamicToo- r <- pipeLoop next_phase output_fn- setDynFlags $ dynamicTooMkDynamicDynFlags dflags- -- TODO shouldn't ignore result:- _ <- pipeLoop phase input_fn- return r- ifGeneratingDynamicToo dflags dynToo noDynToo- _ -> pipeLoop next_phase output_fn+ -- if Opt_BuildDynamicToo is set and if the platform+ -- supports it, we first run the backend to generate+ -- the dynamic objects and then re-run it to generate+ -- the non-dynamic ones.+ let dflags' = setDynamicNow dflags -- set "dynamicNow"+ setDynFlags dflags'+ (next_phase, output_fn) <- runHookedPhase phase input_fn dflags'+ _ <- pipeLoop next_phase output_fn+ -- TODO: we probably shouldn't ignore the result of+ -- the dynamic compilation+ setDynFlags dflags -- restore flags without "dynamicNow" set+ noDynToo+ dynamicTooState dflags >>= \case+ DT_Dont -> noDynToo+ DT_Failed -> noDynToo+ DT_OK -> dynToo+ DT_Dyn -> noDynToo+ -- it shouldn't be possible to be in this last case+ -- here. It would mean that we executed the whole+ -- pipeline with DynamicNow and Opt_BuildDynamicToo set.+ --+ -- When we restart the whole pipeline for -dynamic-too+ -- we set DynamicNow but we unset Opt_BuildDynamicToo so+ -- it's weird.+ _ -> do+ (next_phase, output_fn) <- runHookedPhase phase input_fn dflags+ pipeLoop next_phase output_fn runHookedPhase :: PhasePlus -> FilePath -> DynFlags -> CompPipeline (PhasePlus, FilePath)@@ -1219,12 +1257,15 @@ -- run the compiler! let msg hsc_env _ what _ = oneShotMsg hsc_env what- (result, plugin_dflags) <-+ (result, plugin_hsc_env) <- liftIO $ hscIncrementalCompile True Nothing (Just msg) hsc_env' mod_summary source_unchanged Nothing (1,1) - -- In the rest of the pipeline use the dflags with plugin info- setDynFlags plugin_dflags+ -- In the rest of the pipeline use the loaded plugins+ setPlugins (hsc_plugins plugin_hsc_env)+ (hsc_static_plugins plugin_hsc_env)+ -- "driver" plugins may have modified the DynFlags so we update them+ setDynFlags (hsc_dflags plugin_hsc_env) return (HscOut src_flavour mod_name result, panic "HscOut doesn't have an input filename")@@ -1263,8 +1304,8 @@ hscs_mod_location = mod_location, hscs_mod_details = mod_details, hscs_partial_iface = partial_iface,- hscs_old_iface_hash = mb_old_iface_hash,- hscs_iface_dflags = iface_dflags }+ hscs_old_iface_hash = mb_old_iface_hash+ } -> do output_fn <- phaseOutputFilename next_phase PipeState{hsc_env=hsc_env'} <- getPipeState@@ -1272,17 +1313,17 @@ (outputFilename, mStub, foreign_files, cg_infos) <- liftIO $ hscGenHardCode hsc_env' cgguts mod_location output_fn - final_iface <- liftIO (mkFullIface hsc_env'{hsc_dflags=iface_dflags} partial_iface (Just cg_infos))+ let dflags = hsc_dflags hsc_env'+ final_iface <- liftIO (mkFullIface hsc_env' partial_iface (Just cg_infos)) let final_mod_details- | gopt Opt_OmitInterfacePragmas iface_dflags+ | gopt Opt_OmitInterfacePragmas dflags = mod_details | otherwise = {-# SCC updateModDetailsIdInfos #-} updateModDetailsIdInfos cg_infos mod_details setIface final_iface final_mod_details -- See Note [Writing interface files]- let if_dflags = dflags `gopt_unset` Opt_BuildDynamicToo- liftIO $ hscMaybeWriteIface if_dflags final_iface mb_old_iface_hash mod_location+ liftIO $ hscMaybeWriteIface dflags False final_iface mb_old_iface_hash mod_location stub_o <- liftIO (mapM (compileStub hsc_env') mStub) foreign_os <- liftIO $@@ -1727,308 +1768,7 @@ _other -> return [] --------------------------------------------------------------------------------- Static linking, of .o files --- The list of packages passed to link is the list of packages on--- which this program depends, as discovered by the compilation--- manager. It is combined with the list of packages that the user--- specifies on the command line with -package flags.------ In one-shot linking mode, we can't discover the package--- dependencies (because we haven't actually done any compilation or--- read any interface files), so the user must explicitly specify all--- the packages.--{--Note [-Xlinker -rpath vs -Wl,-rpath]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~---Wl takes a comma-separated list of options which in the case of--Wl,-rpath -Wl,some,path,with,commas parses the path with commas-as separate options.-Buck, the build system, produces paths with commas in them.---Xlinker doesn't have this disadvantage and as far as I can tell-it is supported by both gcc and clang. Anecdotally nvcc supports--Xlinker, but not -Wl.--}--linkBinary :: DynFlags -> [FilePath] -> [UnitId] -> IO ()-linkBinary = linkBinary' False--linkBinary' :: Bool -> DynFlags -> [FilePath] -> [UnitId] -> IO ()-linkBinary' staticLink dflags o_files dep_units = do- let platform = targetPlatform dflags- toolSettings' = toolSettings dflags- verbFlags = getVerbFlags dflags- output_fn = exeFileName staticLink dflags- home_unit = mkHomeUnitFromFlags dflags-- -- get the full list of packages to link with, by combining the- -- explicit packages with the auto packages and all of their- -- dependencies, and eliminating duplicates.-- full_output_fn <- if isAbsolute output_fn- then return output_fn- else do d <- getCurrentDirectory- return $ normalise (d </> output_fn)- pkg_lib_paths <- getUnitLibraryPath- (initSDocContext dflags defaultUserStyle)- (unitState dflags)- home_unit- (ways dflags)- dep_units- let pkg_lib_path_opts = concatMap get_pkg_lib_path_opts pkg_lib_paths- get_pkg_lib_path_opts l- | osElfTarget (platformOS platform) &&- dynLibLoader dflags == SystemDependent &&- WayDyn `elem` ways dflags- = let libpath = if gopt Opt_RelativeDynlibPaths dflags- then "$ORIGIN" </>- (l `makeRelativeTo` full_output_fn)- else l- -- See Note [-Xlinker -rpath vs -Wl,-rpath]- rpath = if gopt Opt_RPath dflags- then ["-Xlinker", "-rpath", "-Xlinker", libpath]- else []- -- Solaris 11's linker does not support -rpath-link option. It silently- -- ignores it and then complains about next option which is -l<some- -- dir> as being a directory and not expected object file, E.g- -- ld: elf error: file- -- /tmp/ghc-src/libraries/base/dist-install/build:- -- elf_begin: I/O error: region read: Is a directory- rpathlink = if (platformOS platform) == OSSolaris2- then []- else ["-Xlinker", "-rpath-link", "-Xlinker", l]- in ["-L" ++ l] ++ rpathlink ++ rpath- | osMachOTarget (platformOS platform) &&- dynLibLoader dflags == SystemDependent &&- WayDyn `elem` ways dflags &&- gopt Opt_RPath dflags- = let libpath = if gopt Opt_RelativeDynlibPaths dflags- then "@loader_path" </>- (l `makeRelativeTo` full_output_fn)- else l- in ["-L" ++ l] ++ ["-Xlinker", "-rpath", "-Xlinker", libpath]- | otherwise = ["-L" ++ l]-- pkg_lib_path_opts <-- if gopt Opt_SingleLibFolder dflags- then do- libs <- getLibs dflags dep_units- tmpDir <- newTempDir dflags- sequence_ [ copyFile lib (tmpDir </> basename)- | (lib, basename) <- libs]- return [ "-L" ++ tmpDir ]- else pure pkg_lib_path_opts-- let- dead_strip- | gopt Opt_WholeArchiveHsLibs dflags = []- | otherwise = if osSubsectionsViaSymbols (platformOS platform)- then ["-Wl,-dead_strip"]- else []- let lib_paths = libraryPaths dflags- let lib_path_opts = map ("-L"++) lib_paths-- extraLinkObj <- mkExtraObjToLinkIntoBinary dflags- noteLinkObjs <- mkNoteObjsToLinkIntoBinary dflags dep_units-- let- (pre_hs_libs, post_hs_libs)- | gopt Opt_WholeArchiveHsLibs dflags- = if platformOS platform == OSDarwin- then (["-Wl,-all_load"], [])- -- OS X does not have a flag to turn off -all_load- else (["-Wl,--whole-archive"], ["-Wl,--no-whole-archive"])- | otherwise- = ([],[])-- pkg_link_opts <- do- (package_hs_libs, extra_libs, other_flags) <- getUnitLinkOpts dflags dep_units- return $ if staticLink- then package_hs_libs -- If building an executable really means making a static- -- library (e.g. iOS), then we only keep the -l options for- -- HS packages, because libtool doesn't accept other options.- -- In the case of iOS these need to be added by hand to the- -- final link in Xcode.- else other_flags ++ dead_strip- ++ pre_hs_libs ++ package_hs_libs ++ post_hs_libs- ++ extra_libs- -- -Wl,-u,<sym> contained in other_flags- -- needs to be put before -l<package>,- -- otherwise Solaris linker fails linking- -- a binary with unresolved symbols in RTS- -- which are defined in base package- -- the reason for this is a note in ld(1) about- -- '-u' option: "The placement of this option- -- on the command line is significant.- -- This option must be placed before the library- -- that defines the symbol."-- -- frameworks- pkg_framework_opts <- getUnitFrameworkOpts dflags platform dep_units- let framework_opts = getFrameworkOpts dflags platform-- -- probably _stub.o files- let extra_ld_inputs = ldInputs dflags-- rc_objs <- maybeCreateManifest dflags output_fn-- let link dflags args | staticLink = GHC.SysTools.runLibtool dflags args- | platformOS platform == OSDarwin- = GHC.SysTools.runLink dflags args >> GHC.SysTools.runInjectRPaths dflags pkg_lib_paths output_fn- | otherwise- = GHC.SysTools.runLink dflags args-- link dflags (- map GHC.SysTools.Option verbFlags- ++ [ GHC.SysTools.Option "-o"- , GHC.SysTools.FileOption "" output_fn- ]- ++ libmLinkOpts- ++ map GHC.SysTools.Option (- []-- -- See Note [No PIE when linking]- ++ picCCOpts dflags-- -- Permit the linker to auto link _symbol to _imp_symbol.- -- This lets us link against DLLs without needing an "import library".- ++ (if platformOS platform == OSMinGW32- then ["-Wl,--enable-auto-import"]- else [])-- -- '-no_compact_unwind'- -- C++/Objective-C exceptions cannot use optimised- -- stack unwinding code. The optimised form is the- -- default in Xcode 4 on at least x86_64, and- -- without this flag we're also seeing warnings- -- like- -- ld: warning: could not create compact unwind for .LFB3: non-standard register 5 being saved in prolog- -- on x86.- ++ (if toolSettings_ldSupportsCompactUnwind toolSettings' &&- not staticLink &&- (platformOS platform == OSDarwin) &&- case platformArch platform of- ArchX86 -> True- ArchX86_64 -> True- ArchARM {} -> True- ArchARM64 -> True- _ -> False- then ["-Wl,-no_compact_unwind"]- else [])-- -- '-Wl,-read_only_relocs,suppress'- -- ld gives loads of warnings like:- -- ld: warning: text reloc in _base_GHCziArr_unsafeArray_info to _base_GHCziArr_unsafeArray_closure- -- when linking any program. We're not sure- -- whether this is something we ought to fix, but- -- for now this flags silences them.- ++ (if platformOS platform == OSDarwin &&- platformArch platform == ArchX86 &&- not staticLink- then ["-Wl,-read_only_relocs,suppress"]- else [])-- ++ (if toolSettings_ldIsGnuLd toolSettings' &&- not (gopt Opt_WholeArchiveHsLibs dflags)- then ["-Wl,--gc-sections"]- else [])-- ++ o_files- ++ lib_path_opts)- ++ extra_ld_inputs- ++ map GHC.SysTools.Option (- rc_objs- ++ framework_opts- ++ pkg_lib_path_opts- ++ extraLinkObj:noteLinkObjs- ++ pkg_link_opts- ++ pkg_framework_opts- ++ (if platformOS platform == OSDarwin- -- dead_strip_dylibs, will remove unused dylibs, and thus save- -- space in the load commands. The -headerpad is necessary so- -- that we can inject more @rpath's later for the left over- -- libraries during runInjectRpaths phase.- --- -- See Note [Dynamic linking on macOS].- then [ "-Wl,-dead_strip_dylibs", "-Wl,-headerpad,8000" ]- else [])- ))--exeFileName :: Bool -> DynFlags -> FilePath-exeFileName staticLink dflags- | Just s <- outputFile dflags =- case platformOS (targetPlatform dflags) of- OSMinGW32 -> s <?.> "exe"- _ -> if staticLink- then s <?.> "a"- else s- | otherwise =- if platformOS (targetPlatform dflags) == OSMinGW32- then "main.exe"- else if staticLink- then "liba.a"- else "a.out"- where s <?.> ext | null (takeExtension s) = s <.> ext- | otherwise = s--maybeCreateManifest- :: DynFlags- -> FilePath -- filename of executable- -> IO [FilePath] -- extra objects to embed, maybe-maybeCreateManifest dflags exe_filename- | platformOS (targetPlatform dflags) == OSMinGW32 &&- gopt Opt_GenManifest dflags- = do let manifest_filename = exe_filename <.> "manifest"-- writeFile manifest_filename $- "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"++- " <assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">\n"++- " <assemblyIdentity version=\"1.0.0.0\"\n"++- " processorArchitecture=\"X86\"\n"++- " name=\"" ++ dropExtension exe_filename ++ "\"\n"++- " type=\"win32\"/>\n\n"++- " <trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v3\">\n"++- " <security>\n"++- " <requestedPrivileges>\n"++- " <requestedExecutionLevel level=\"asInvoker\" uiAccess=\"false\"/>\n"++- " </requestedPrivileges>\n"++- " </security>\n"++- " </trustInfo>\n"++- "</assembly>\n"-- -- Windows will find the manifest file if it is named- -- foo.exe.manifest. However, for extra robustness, and so that- -- we can move the binary around, we can embed the manifest in- -- the binary itself using windres:- if not (gopt Opt_EmbedManifest dflags) then return [] else do-- rc_filename <- newTempName dflags TFL_CurrentModule "rc"- rc_obj_filename <-- newTempName dflags TFL_GhcSession (objectSuf dflags)-- writeFile rc_filename $- "1 24 MOVEABLE PURE " ++ show manifest_filename ++ "\n"- -- magic numbers :-)- -- show is a bit hackish above, but we need to escape the- -- backslashes in the path.-- runWindres dflags $ map GHC.SysTools.Option $- ["--input="++rc_filename,- "--output="++rc_obj_filename,- "--output-format=coff"]- -- no FileOptions here: windres doesn't like seeing- -- backslashes, apparently-- removeFile manifest_filename-- return [rc_obj_filename]- | otherwise = return []-- linkDynLibCheck :: DynFlags -> [String] -> [UnitId] -> IO () linkDynLibCheck dflags o_files dep_units = do when (haveRtsOptsFlags dflags) $@@ -2038,47 +1778,6 @@ text " Call hs_init_ghc() from your main() function to set these options.") linkDynLib dflags o_files dep_units --- | Linking a static lib will not really link anything. It will merely produce--- a static archive of all dependent static libraries. The resulting library--- will still need to be linked with any remaining link flags.-linkStaticLib :: DynFlags -> [String] -> [UnitId] -> IO ()-linkStaticLib dflags o_files dep_units = do- let extra_ld_inputs = [ f | FileOption _ f <- ldInputs dflags ]- modules = o_files ++ extra_ld_inputs- output_fn = exeFileName True dflags- home_unit = mkHomeUnitFromFlags dflags-- full_output_fn <- if isAbsolute output_fn- then return output_fn- else do d <- getCurrentDirectory- return $ normalise (d </> output_fn)- output_exists <- doesFileExist full_output_fn- (when output_exists) $ removeFile full_output_fn-- pkg_cfgs_init <- getPreloadUnitsAnd- (initSDocContext dflags defaultUserStyle)- (unitState dflags)- home_unit- dep_units-- let pkg_cfgs- | gopt Opt_LinkRts dflags- = pkg_cfgs_init- | otherwise- = filter ((/= rtsUnitId) . unitId) pkg_cfgs_init-- archives <- concatMapM (collectArchives dflags) pkg_cfgs-- ar <- foldl mappend- <$> (Archive <$> mapM loadObj modules)- <*> mapM loadAr archives-- if toolSettings_ldIsGnuLd (toolSettings dflags)- then writeGNUAr output_fn $ afilter (not . isGNUSymdef) ar- else writeBSDAr output_fn $ afilter (not . isBSDSymdef) ar-- -- run ranlib over the archive. write*Ar does *not* create the symbol index.- runRanlib dflags [GHC.SysTools.FileOption "" output_fn] -- ----------------------------------------------------------------------------- -- Running CPP
compiler/GHC/HsToCore.hs view
@@ -198,7 +198,7 @@ ; endPassIO hsc_env print_unqual CoreDesugarOpt ds_binds ds_rules_for_imps ; let used_names = mkUsedNames tcg_env- pluginModules = map lpModule (cachedPlugins (hsc_dflags hsc_env))+ pluginModules = map lpModule (hsc_plugins hsc_env) home_unit = hsc_home_unit hsc_env ; deps <- mkDependencies (homeUnitId home_unit) (map mi_module pluginModules) tcg_env
compiler/GHC/HsToCore/Docs.hs view
@@ -141,7 +141,7 @@ -- instanceMap. getInstLoc :: InstDecl (GhcPass p) -> SrcSpan getInstLoc = \case- ClsInstD _ (ClsInstDecl { cid_poly_ty = ty }) -> getLoc (hsSigType ty)+ ClsInstD _ (ClsInstDecl { cid_poly_ty = ty }) -> getLoc ty -- The Names of data and type family instances have their SrcSpan's attached -- to the *type constructor*. For example, the Name "D:R:Foo:Int" would have -- its SrcSpan attached here:@@ -149,12 +149,12 @@ -- type instance Foo Int = Bool -- ^^^ DataFamInstD _ (DataFamInstDecl- { dfid_eqn = HsIB { hsib_body = FamEqn { feqn_tycon = L l _ }}}) -> l+ { dfid_eqn = FamEqn { feqn_tycon = L l _ }}) -> l -- Since CoAxioms' Names refer to the whole line for type family instances -- in particular, we need to dig a bit deeper to pull out the entire -- equation. This does not happen for data family instances, for some reason. TyFamInstD _ (TyFamInstDecl- { tfid_eqn = HsIB { hsib_body = FamEqn { feqn_tycon = L l _ }}}) -> l+ { tfid_eqn = FamEqn { feqn_tycon = L l _ }}) -> l -- | Get all subordinate declarations inside a declaration, and their docs. -- A subordinate declaration is something like the associate type or data@@ -164,12 +164,12 @@ -> [(Name, [(HsDocString)], Map Int (HsDocString))] subordinates instMap decl = case decl of InstD _ (ClsInstD _ d) -> do- DataFamInstDecl { dfid_eqn = HsIB { hsib_body =+ DataFamInstDecl { dfid_eqn = FamEqn { feqn_tycon = L l _- , feqn_rhs = defn }}} <- unLoc <$> cid_datafam_insts d+ , feqn_rhs = defn }} <- unLoc <$> cid_datafam_insts d [ (n, [], M.empty) | Just n <- [lookupSrcSpan l instMap] ] ++ dataSubs defn - InstD _ (DataFamInstD _ (DataFamInstDecl (HsIB { hsib_body = d })))+ InstD _ (DataFamInstD _ (DataFamInstDecl d)) -> dataSubs (feqn_rhs d) TyClD _ d | isClassDecl d -> classSubs d | isDataDecl d -> dataSubs (tcdDataDefn d)@@ -205,12 +205,8 @@ DctMulti _ tys -> mapMaybe extract_deriv_ty tys extract_deriv_ty :: LHsSigType GhcRn -> Maybe (SrcSpan, LHsDocString)- extract_deriv_ty (HsIB{hsib_body = L l ty}) =+ extract_deriv_ty (L l (HsSig{sig_body = L _ ty})) = case ty of- -- deriving (forall a. C a {- ^ Doc comment -})- HsForAllTy{ hst_tele = HsForAllInvis{}- , hst_body = L _ (HsDocTy _ _ doc) }- -> Just (l, doc) -- deriving (C a {- ^ Doc comment -}) HsDocTy _ _ doc -> Just (l, doc) _ -> Nothing@@ -259,10 +255,10 @@ -- | Extract function argument docs from inside top-level decls. declTypeDocs :: HsDecl GhcRn -> Map Int (HsDocString) declTypeDocs = \case- SigD _ (TypeSig _ _ ty) -> typeDocs (unLoc (hsSigWcType ty))- SigD _ (ClassOpSig _ _ _ ty) -> typeDocs (unLoc (hsSigType ty))- SigD _ (PatSynSig _ _ ty) -> typeDocs (unLoc (hsSigType ty))- ForD _ (ForeignImport _ _ ty _) -> typeDocs (unLoc (hsSigType ty))+ SigD _ (TypeSig _ _ ty) -> sigTypeDocs (unLoc (dropWildCards ty))+ SigD _ (ClassOpSig _ _ _ ty) -> sigTypeDocs (unLoc ty)+ SigD _ (PatSynSig _ _ ty) -> sigTypeDocs (unLoc ty)+ ForD _ (ForeignImport _ _ ty _) -> sigTypeDocs (unLoc ty) TyClD _ (SynDecl { tcdRhs = ty }) -> typeDocs (unLoc ty) _ -> M.empty @@ -288,6 +284,10 @@ HsFunTy _ _ _ ty -> go (n+1) (unLoc ty) HsDocTy _ _ doc -> M.singleton n (unLoc doc) _ -> M.empty++-- | Extract function argument docs from inside types.+sigTypeDocs :: HsSigType GhcRn -> Map Int HsDocString+sigTypeDocs (HsSig{sig_body = body}) = typeDocs (unLoc body) -- | The top-level declarations of a module that we care about, -- ordered by source location, with documentation attached if it exists.
compiler/GHC/HsToCore/Foreign/Call.hs view
@@ -21,9 +21,7 @@ #include "GhclibHsVersions.h" - import GHC.Prelude-import GHC.Platform import GHC.Core @@ -41,7 +39,6 @@ import GHC.Core.Multiplicity import GHC.Types.Id ( Id ) import GHC.Core.Coercion-import GHC.Builtin.PrimOps import GHC.Builtin.Types.Prim import GHC.Core.TyCon import GHC.Builtin.Types@@ -346,7 +343,7 @@ -- The type might contain foralls (eg. for dummy type arguments, -- referring to 'Ptr a' is legal).- | Just (tyvar, rest) <- splitForAllTy_maybe result_ty+ | Just (tyvar, rest) <- splitForAllTyCoVar_maybe result_ty = do { (maybe_ty, wrapper) <- resultWrapper rest ; return (maybe_ty, \e -> Lam tyvar (wrapper e)) } @@ -355,36 +352,13 @@ | Just (tycon, tycon_arg_tys) <- maybe_tc_app , Just data_con <- isDataProductTyCon_maybe tycon -- One constructor, no existentials , [Scaled _ unwrapped_res_ty] <- dataConInstOrigArgTys data_con tycon_arg_tys -- One argument- = do { dflags <- getDynFlags- ; let platform = targetPlatform dflags- ; (maybe_ty, wrapper) <- resultWrapper unwrapped_res_ty- ; let narrow_wrapper = maybeNarrow platform tycon- marshal_con e = Var (dataConWrapId data_con)+ = do { (maybe_ty, wrapper) <- resultWrapper unwrapped_res_ty+ ; let marshal_con e = Var (dataConWrapId data_con) `mkTyApps` tycon_arg_tys- `App` wrapper (narrow_wrapper e)+ `App` wrapper e ; return (maybe_ty, marshal_con) } | otherwise = pprPanic "resultWrapper" (ppr result_ty) where maybe_tc_app = splitTyConApp_maybe result_ty---- When the result of a foreign call is smaller than the word size, we--- need to sign- or zero-extend the result up to the word size. The C--- standard appears to say that this is the responsibility of the--- caller, not the callee.--maybeNarrow :: Platform -> TyCon -> (CoreExpr -> CoreExpr)-maybeNarrow platform tycon- | tycon `hasKey` int8TyConKey = \e -> App (Var (mkPrimOpId Narrow8IntOp)) e- | tycon `hasKey` int16TyConKey = \e -> App (Var (mkPrimOpId Narrow16IntOp)) e- | tycon `hasKey` int32TyConKey- , platformWordSizeInBytes platform > 4- = \e -> App (Var (mkPrimOpId Narrow32IntOp)) e-- | tycon `hasKey` word8TyConKey = \e -> App (Var (mkPrimOpId Narrow8WordOp)) e- | tycon `hasKey` word16TyConKey = \e -> App (Var (mkPrimOpId Narrow16WordOp)) e- | tycon `hasKey` word32TyConKey- , platformWordSizeInBytes platform > 4- = \e -> App (Var (mkPrimOpId Narrow32WordOp)) e- | otherwise = id
compiler/GHC/HsToCore/Foreign/Decl.hs view
@@ -212,7 +212,7 @@ dsFCall fn_id co fcall mDeclHeader = do let ty = coercionLKind co- (tv_bndrs, rho) = tcSplitForAllVarBndrs ty+ (tv_bndrs, rho) = tcSplitForAllTyVarBinders ty (arg_tys, io_res_ty) = tcSplitFunTys rho args <- newSysLocalsDs arg_tys -- no FFI levity-polymorphism@@ -316,7 +316,7 @@ dsPrimCall fn_id co fcall = do let ty = coercionLKind co- (tvs, fun_ty) = tcSplitForAllTys ty+ (tvs, fun_ty) = tcSplitForAllInvisTyVars ty (arg_tys, io_res_ty) = tcSplitFunTys fun_ty args <- newSysLocalsDs arg_tys -- no FFI levity-polymorphism@@ -453,7 +453,7 @@ to be entered using an external calling convention (stdcall, ccall). -}- adj_args = [ mkIntLitInt platform (ccallConvToInt cconv)+ adj_args = [ mkIntLit platform (fromIntegral (ccallConvToInt cconv)) , Var stbl_value , Lit (LitLabel fe_nm mb_sz_args IsFunction) , Lit (mkLitString typestring)@@ -489,7 +489,7 @@ where ty = coercionLKind co0- (tvs,sans_foralls) = tcSplitForAllTys ty+ (tvs,sans_foralls) = tcSplitForAllInvisTyVars ty ([Scaled arg_mult arg_ty], fn_res_ty) = tcSplitFunTys sans_foralls Just (io_tc, res_ty) = tcSplitIOType_maybe fn_res_ty -- Must have an IO type; hence Just@@ -849,6 +849,12 @@ = case typePrimRep1 (getPrimTyOf ty) of IntRep -> signed_word WordRep -> unsigned_word+ Int8Rep -> 'B'+ Word8Rep -> 'b'+ Int16Rep -> 'S'+ Word16Rep -> 's'+ Int32Rep -> 'W'+ Word32Rep -> 'w' Int64Rep -> 'L' Word64Rep -> 'l' AddrRep -> 'p'
compiler/GHC/HsToCore/Pmc.hs view
@@ -381,7 +381,10 @@ case vars of -- See #11245 [] -> text "Guards do not cover entire pattern space" _ -> let us = map (\nabla -> pprUncovered nabla vars) nablas- in hang (text "Patterns not matched:") 4+ pp_tys = pprQuotedList $ map idType vars+ in hang+ (text "Patterns of type" <+> pp_tys <+> text "not matched:")+ 4 (vcat (take maxPatterns us) $$ dots maxPatterns us) approx_msg = vcat
compiler/GHC/HsToCore/Pmc/Ppr.hs view
@@ -136,26 +136,13 @@ -- | Pretty print a variable, but remember to prettify the names of the variables -- that refer to neg-literals. The ones that cannot be shown are printed as--- underscores. Even with a type signature, if it's not too noisy.+-- underscores. pprPmVar :: PprPrec -> Id -> PmPprM SDoc--- Type signature is "too noisy" by my definition if it needs to parenthesize.--- I like "not matched: _ :: Proxy (DIdEnv (Id, SDoc))",--- but I don't like "not matched: (_ :: stuff) (_:_) (_ :: Proxy (DIdEnv (Id, SDoc)))"--- The useful information in the latter case is the constructor that we missed,--- not the types of the wildcards in the places that aren't matched as a result. pprPmVar prec x = do nabla <- ask case lookupSolution nabla x of Just (PACA alt _tvs args) -> pprPmAltCon prec alt args- Nothing -> fromMaybe typed_wildcard <$> checkRefuts x- where- -- if we have no info about the parameter and would just print a- -- wildcard, also show its type.- typed_wildcard- | prec <= sigPrec- = underscore <+> text "::" <+> ppr (idType x)- | otherwise- = underscore+ Nothing -> fromMaybe underscore <$> checkRefuts x pprPmAltCon :: PprPrec -> PmAltCon -> [Id] -> PmPprM SDoc pprPmAltCon _prec (PmAltLit l) _ = pure (ppr l)
compiler/GHC/HsToCore/Quote.hs view
@@ -360,7 +360,6 @@ = [] get_scoped_tvs_from_sig :: LHsSigType GhcRn -> [Name]-get_scoped_tvs_from_sig sig -- Collect both implicit and explicit quantified variables, since -- the types in instance heads, as well as `via` types in DerivingVia, can -- bring implicitly quantified type variables into scope, e.g.,@@ -369,10 +368,8 @@ -- m = n @a -- -- See also Note [Scoped type variables in quotes]- | HsIB { hsib_ext = implicit_vars- , hsib_body = hs_ty } <- sig- , (explicit_vars, _) <- splitLHsForAllTyInvis hs_ty- = implicit_vars ++ hsLTyVarNames explicit_vars+get_scoped_tvs_from_sig (L _ (HsSig{sig_bndrs = outer_bndrs})) =+ hsOuterTyVarNames outer_bndrs {- Notes @@ -508,7 +505,11 @@ repKiSigD :: LStandaloneKindSig GhcRn -> MetaM (SrcSpan, Core (M TH.Dec)) repKiSigD (L loc kisig) = case kisig of- StandaloneKindSig _ v ki -> rep_ty_sig kiSigDName loc ki v+ StandaloneKindSig _ v ki -> do+ MkC th_v <- lookupLOcc v+ MkC th_ki <- repHsSigType ki+ dec <- rep2 kiSigDName [th_v, th_ki]+ pure (loc, dec) ------------------------- repDataDefn :: Core TH.Name@@ -689,27 +690,21 @@ ; repTySynInst eqn1 } repTyFamEqn :: TyFamInstEqn GhcRn -> MetaM (Core (M TH.TySynEqn))-repTyFamEqn (HsIB { hsib_ext = var_names- , hsib_body = FamEqn { feqn_tycon = tc_name- , feqn_bndrs = mb_bndrs- , feqn_pats = tys- , feqn_fixity = fixity- , feqn_rhs = rhs }})+repTyFamEqn (FamEqn { feqn_tycon = tc_name+ , feqn_bndrs = outer_bndrs+ , feqn_pats = tys+ , feqn_fixity = fixity+ , feqn_rhs = rhs }) = do { tc <- lookupLOcc tc_name -- See note [Binders and occurrences]- ; let hs_tvs = HsQTvs { hsq_ext = var_names- , hsq_explicit = fromMaybe [] mb_bndrs }- ; addTyClTyVarBinds hs_tvs $ \ _ ->- do { mb_bndrs1 <- repMaybeListM tyVarBndrUnitTyConName- repTyVarBndr- mb_bndrs- ; tys1 <- case fixity of+ ; addHsOuterFamEqnTyVarBinds outer_bndrs $ \mb_exp_bndrs ->+ do { tys1 <- case fixity of Prefix -> repTyArgs (repNamedTyCon tc) tys Infix -> do { (HsValArg t1: HsValArg t2: args) <- checkTys tys ; t1' <- repLTy t1 ; t2' <- repLTy t2 ; repTyArgs (repTInfix t1' tc t2') args } ; rhs1 <- repLTy rhs- ; repTySynEqn mb_bndrs1 tys1 rhs1 } }+ ; repTySynEqn mb_exp_bndrs tys1 rhs1 } } where checkTys :: [LHsTypeArg GhcRn] -> MetaM [LHsTypeArg GhcRn] checkTys tys@(HsValArg _:HsValArg _:_) = return tys checkTys _ = panic "repTyFamEqn:checkTys"@@ -726,26 +721,20 @@ repDataFamInstD :: DataFamInstDecl GhcRn -> MetaM (Core (M TH.Dec)) repDataFamInstD (DataFamInstDecl { dfid_eqn =- (HsIB { hsib_ext = var_names- , hsib_body = FamEqn { feqn_tycon = tc_name- , feqn_bndrs = mb_bndrs+ FamEqn { feqn_tycon = tc_name+ , feqn_bndrs = outer_bndrs , feqn_pats = tys , feqn_fixity = fixity- , feqn_rhs = defn }})})+ , feqn_rhs = defn }}) = do { tc <- lookupLOcc tc_name -- See note [Binders and occurrences]- ; let hs_tvs = HsQTvs { hsq_ext = var_names- , hsq_explicit = fromMaybe [] mb_bndrs }- ; addTyClTyVarBinds hs_tvs $ \ _ ->- do { mb_bndrs1 <- repMaybeListM tyVarBndrUnitTyConName- repTyVarBndr- mb_bndrs- ; tys1 <- case fixity of+ ; addHsOuterFamEqnTyVarBinds outer_bndrs $ \mb_exp_bndrs ->+ do { tys1 <- case fixity of Prefix -> repTyArgs (repNamedTyCon tc) tys Infix -> do { (HsValArg t1: HsValArg t2: args) <- checkTys tys ; t1' <- repLTy t1 ; t2' <- repLTy t2 ; repTyArgs (repTInfix t1' tc t2') args }- ; repDataDefn tc (Right (mb_bndrs1, tys1)) defn } }+ ; repDataDefn tc (Right (mb_exp_bndrs, tys1)) defn } } where checkTys :: [LHsTypeArg GhcRn] -> MetaM [LHsTypeArg GhcRn] checkTys tys@(HsValArg _: HsValArg _: _) = return tys@@ -892,26 +881,28 @@ else rep2 forallCName ([unC ex_bndrs, unC ctxt', unC c']) } -repC (L _ (ConDeclGADT { con_g_ext = imp_tvs- , con_names = cons- , con_qvars = exp_tvs+repC (L _ (ConDeclGADT { con_names = cons+ , con_bndrs = L _ outer_bndrs , con_mb_cxt = mcxt , con_g_args = args , con_res_ty = res_ty }))- | null imp_tvs && null exp_tvs -- No implicit or explicit variables+ | null_outer_imp_tvs && null_outer_exp_tvs+ -- No implicit or explicit variables , Nothing <- mcxt -- No context -- ==> no need for a forall = repGadtDataCons cons args res_ty | otherwise- = addTyVarBinds exp_tvs imp_tvs $ \ ex_bndrs ->+ = addHsOuterSigTyVarBinds outer_bndrs $ \ outer_bndrs' -> -- See Note [Don't quantify implicit type variables in quotes] do { c' <- repGadtDataCons cons args res_ty ; ctxt' <- repMbContext mcxt- ; if null exp_tvs && isNothing mcxt+ ; if null_outer_exp_tvs && isNothing mcxt then return c'- else rep2 forallCName ([unC ex_bndrs, unC ctxt', unC c']) }-+ else rep2 forallCName ([unC outer_bndrs', unC ctxt', unC c']) }+ where+ null_outer_imp_tvs = nullOuterImplicit outer_bndrs+ null_outer_exp_tvs = nullOuterExplicit outer_bndrs repMbContext :: Maybe (LHsContext GhcRn) -> MetaM (Core (M TH.Cxt)) repMbContext Nothing = repContext []@@ -962,7 +953,7 @@ DctMulti _ tys -> rep_deriv_tys tys rep_deriv_tys :: [LHsSigType GhcRn] -> MetaM (Core [M TH.Type])- rep_deriv_tys = repListM typeTyConName (repLTy . hsSigType)+ rep_deriv_tys = repListM typeTyConName repHsSigType rep_meth_sigs_binds :: [LSig GhcRn] -> LHsBinds GhcRn -> MetaM ([GenSymBind], [Core (M TH.Dec)])@@ -1014,13 +1005,20 @@ rep_ty_sig_tvs :: [LHsTyVarBndr Specificity GhcRn] -> MetaM (Core [M TH.TyVarBndrSpec]) rep_ty_sig_tvs explicit_tvs- = let rep_in_scope_tv tv = do { name <- lookupBinder (hsLTyVarName tv)- ; repTyVarBndrWithKind tv name } in- repListM tyVarBndrSpecTyConName rep_in_scope_tv+ = repListM tyVarBndrSpecTyConName repTyVarBndr explicit_tvs- -- NB: Don't pass any implicit type variables to repList above- -- See Note [Don't quantify implicit type variables in quotes] +-- Desugar the outer type variable binders in an 'LHsSigType', making+-- sure not to gensym them.+-- See Note [Scoped type variables in quotes]+-- and Note [Don't quantify implicit type variables in quotes]+rep_ty_sig_outer_tvs :: HsOuterSigTyVarBndrs GhcRn+ -> MetaM (Core [M TH.TyVarBndrSpec])+rep_ty_sig_outer_tvs (HsOuterImplicit{}) =+ coreListM tyVarBndrSpecTyConName []+rep_ty_sig_outer_tvs (HsOuterExplicit{hso_bndrs = explicit_tvs}) =+ rep_ty_sig_tvs explicit_tvs+ -- Desugar a top-level type signature. Unlike 'repHsSigType', this -- deliberately avoids gensymming the type variables. -- See Note [Scoped type variables in quotes]@@ -1039,15 +1037,14 @@ -- and Note [Don't quantify implicit type variables in quotes] rep_ty_sig' :: LHsSigType GhcRn -> MetaM (Core (M TH.Type))-rep_ty_sig' sig_ty- | HsIB { hsib_body = hs_ty } <- sig_ty- , (explicit_tvs, ctxt, ty) <- splitLHsSigmaTyInvis hs_ty- = do { th_explicit_tvs <- rep_ty_sig_tvs explicit_tvs+rep_ty_sig' (L _ (HsSig{sig_bndrs = outer_bndrs, sig_body = body}))+ | (ctxt, tau) <- splitLHsQualTy body+ = do { th_explicit_tvs <- rep_ty_sig_outer_tvs outer_bndrs ; th_ctxt <- repLContext ctxt- ; th_ty <- repLTy ty- ; if null explicit_tvs && null (unLoc ctxt)- then return th_ty- else repTForall th_explicit_tvs th_ctxt th_ty }+ ; th_tau <- repLTy tau+ ; if nullOuterExplicit outer_bndrs && null (unLoc ctxt)+ then return th_tau+ else repTForall th_explicit_tvs th_ctxt th_tau } rep_patsyn_ty_sig :: SrcSpan -> LHsSigType GhcRn -> Located Name -> MetaM (SrcSpan, Core (M TH.Dec))@@ -1058,8 +1055,7 @@ -- see Note [Scoped type variables in quotes] -- and Note [Don't quantify implicit type variables in quotes] rep_patsyn_ty_sig loc sig_ty nm- | HsIB { hsib_body = hs_ty } <- sig_ty- , (univs, reqs, exis, provs, ty) <- splitLHsPatSynTy hs_ty+ | (univs, reqs, exis, provs, ty) <- splitLHsPatSynTy sig_ty = do { nm1 <- lookupLOcc nm ; th_univs <- rep_ty_sig_tvs univs ; th_exis <- rep_ty_sig_tvs exis@@ -1167,6 +1163,56 @@ rep_flag SpecifiedSpec = rep2_nw specifiedSpecName [] rep_flag InferredSpec = rep2_nw inferredSpecName [] +addHsOuterFamEqnTyVarBinds ::+ HsOuterFamEqnTyVarBndrs GhcRn+ -> (Core (Maybe [M TH.TyVarBndrUnit]) -> MetaM (Core (M a)))+ -> MetaM (Core (M a))+addHsOuterFamEqnTyVarBinds outer_bndrs thing_inside = do+ elt_ty <- wrapName tyVarBndrUnitTyConName+ case outer_bndrs of+ HsOuterImplicit{hso_ximplicit = imp_tvs} ->+ addTyClTyVarBinds (mk_qtvs imp_tvs []) $ \_th_exp_bndrs ->+ thing_inside $ coreNothingList elt_ty+ HsOuterExplicit{hso_bndrs = exp_bndrs} ->+ addTyClTyVarBinds (mk_qtvs [] exp_bndrs) $ \th_exp_bndrs ->+ thing_inside $ coreJustList elt_ty th_exp_bndrs+ where+ mk_qtvs imp_tvs exp_tvs = HsQTvs { hsq_ext = imp_tvs+ , hsq_explicit = exp_tvs }++addHsOuterSigTyVarBinds ::+ HsOuterSigTyVarBndrs GhcRn+ -> (Core [M TH.TyVarBndrSpec] -> MetaM (Core (M a)))+ -> MetaM (Core (M a))+addHsOuterSigTyVarBinds outer_bndrs thing_inside = case outer_bndrs of+ HsOuterImplicit{hso_ximplicit = imp_tvs} ->+ do th_nil <- coreListM tyVarBndrSpecTyConName []+ addSimpleTyVarBinds imp_tvs $ thing_inside th_nil+ HsOuterExplicit{hso_bndrs = exp_bndrs} ->+ addHsTyVarBinds exp_bndrs thing_inside++-- | If a type implicitly quantifies its outermost type variables, return+-- 'True' if the list of implicitly bound type variables is empty. If a type+-- explicitly quantifies its outermost type variables, always return 'True'.+--+-- This is used in various places to determine if a Template Haskell 'Type'+-- should be headed by a 'ForallT' or not.+nullOuterImplicit :: HsOuterSigTyVarBndrs GhcRn -> Bool+nullOuterImplicit (HsOuterImplicit{hso_ximplicit = imp_tvs}) = null imp_tvs+nullOuterImplicit (HsOuterExplicit{}) = True+ -- Vacuously true, as there is no implicit quantification++-- | If a type explicitly quantifies its outermost type variables, return+-- 'True' if the list of explicitly bound type variables is empty. If a type+-- implicitly quantifies its outermost type variables, always return 'True'.+--+-- This is used in various places to determine if a Template Haskell 'Type'+-- should be headed by a 'ForallT' or not.+nullOuterExplicit :: HsOuterSigTyVarBndrs GhcRn -> Bool+nullOuterExplicit (HsOuterExplicit{hso_bndrs = exp_bndrs}) = null exp_bndrs+nullOuterExplicit (HsOuterImplicit{}) = True+ -- Vacuously true, as there is no outermost explicit quantification+ addSimpleTyVarBinds :: [Name] -- the binders to be added -> MetaM (Core (M a)) -- action in the ext env -> MetaM (Core (M a))@@ -1182,12 +1228,10 @@ addHsTyVarBinds exp_tvs thing_inside = do { fresh_exp_names <- mkGenSyms (hsLTyVarNames exp_tvs) ; term <- addBinds fresh_exp_names $- do { kbs <- repListM (tyVarBndrName @flag @flag') mk_tv_bndr- (exp_tvs `zip` fresh_exp_names)+ do { kbs <- repListM (tyVarBndrName @flag @flag') repTyVarBndr+ exp_tvs ; thing_inside kbs } ; wrapGenSyms fresh_exp_names term }- where- mk_tv_bndr (tv, (_,v)) = repTyVarBndrWithKind tv (coreVar v) addQTyVarBinds :: LHsQTyVars GhcRn -- the binders to be added -> (Core [(M (TH.TyVarBndr ()))] -> MetaM (Core (M a))) -- action in the ext env@@ -1226,26 +1270,12 @@ -- This makes things work for family declarations ; term <- addBinds freshNames $- do { kbs <- repListM tyVarBndrUnitTyConName mk_tv_bndr+ do { kbs <- repListM tyVarBndrUnitTyConName repTyVarBndr (hsQTvExplicit tvs) ; m kbs } ; wrapGenSyms freshNames term }- where- mk_tv_bndr :: LHsTyVarBndr () GhcRn -> MetaM (Core (M (TH.TyVarBndr ())))- mk_tv_bndr tv = do { v <- lookupBinder (hsLTyVarName tv)- ; repTyVarBndrWithKind tv v } --- Produce kinded binder constructors from the Haskell tyvar binders----repTyVarBndrWithKind :: RepTV flag flag' => LHsTyVarBndr flag GhcRn- -> Core TH.Name -> MetaM (Core (M (TH.TyVarBndr flag')))-repTyVarBndrWithKind (L _ (UserTyVar _ fl _)) nm- = repPlainTV nm fl-repTyVarBndrWithKind (L _ (KindedTyVar _ fl _ ki)) nm- = do { ki' <- repLTy ki- ; repKindedTV nm fl ki' }- -- | Represent a type variable binder repTyVarBndr :: RepTV flag flag' => LHsTyVarBndr flag GhcRn -> MetaM (Core (M (TH.TyVarBndr flag')))@@ -1267,17 +1297,14 @@ repCtxt preds repHsSigType :: LHsSigType GhcRn -> MetaM (Core (M TH.Type))-repHsSigType (HsIB { hsib_ext = implicit_tvs- , hsib_body = body })- | (explicit_tvs, ctxt, ty) <- splitLHsSigmaTyInvis body- = addSimpleTyVarBinds implicit_tvs $- -- See Note [Don't quantify implicit type variables in quotes]- addHsTyVarBinds explicit_tvs $ \ th_explicit_tvs ->+repHsSigType (L _ (HsSig { sig_bndrs = outer_bndrs, sig_body = body }))+ | (ctxt, tau) <- splitLHsQualTy body+ = addHsOuterSigTyVarBinds outer_bndrs $ \ th_outer_bndrs -> do { th_ctxt <- repLContext ctxt- ; th_ty <- repLTy ty- ; if null explicit_tvs && null (unLoc ctxt)- then return th_ty- else repTForall th_explicit_tvs th_ctxt th_ty }+ ; th_tau <- repLTy tau+ ; if nullOuterExplicit outer_bndrs && null (unLoc ctxt)+ then pure th_tau+ else repTForall th_outer_bndrs th_ctxt th_tau } -- yield the representation of a list of types repLTys :: [LHsType GhcRn] -> MetaM [Core (M TH.Type)]@@ -2757,11 +2784,10 @@ repLiteral :: HsLit GhcRn -> MetaM (Core TH.Lit) repLiteral (HsStringPrim _ bs)- = do platform <- getPlatform- word8_ty <- lookupType word8TyConName+ = do word8_ty <- lookupType word8TyConName let w8s = unpack bs w8s_expr = map (\w8 -> mkCoreConApps word8DataCon- [mkWordLit platform (toInteger w8)]) w8s+ [mkWord8Lit (toInteger w8)]) w8s rep2_nw stringPrimLName [mkListExpr word8_ty w8s_expr] repLiteral lit = do lit' <- case lit of@@ -2923,23 +2949,11 @@ ------------------- Maybe Lists ------------------ --- Lookup the name and wrap it with the m variable-repMaybeListM :: Name -> (a -> MetaM (Core b))- -> Maybe [a] -> MetaM (Core (Maybe [b]))-repMaybeListM tc_name f xs = do- elt_ty <- wrapName tc_name- repMaybeListT elt_ty f xs---repMaybeListT :: Type -> (a -> MetaM (Core b))- -> Maybe [a] -> MetaM (Core (Maybe [b]))-repMaybeListT elt_ty _ Nothing = coreNothingList elt_ty-repMaybeListT elt_ty f (Just args)- = do { args1 <- mapM f args- ; return $ coreJust' (mkListTy elt_ty) (coreList' elt_ty args1) }+coreJustList :: Type -> Core [a] -> Core (Maybe [a])+coreJustList elt_ty = coreJust' (mkListTy elt_ty) -coreNothingList :: Type -> MetaM (Core (Maybe [a]))-coreNothingList elt_ty = return $ coreNothing' (mkListTy elt_ty)+coreNothingList :: Type -> Core (Maybe [a])+coreNothingList elt_ty = coreNothing' (mkListTy elt_ty) ------------ Literals & Variables -------------------
compiler/GHC/HsToCore/Usage.hs view
@@ -37,6 +37,8 @@ import GHC.Unit.Module.ModIface import GHC.Unit.Module.Deps +import GHC.Linker.Unit+ import GHC.Data.Maybe import Control.Monad (filterM)@@ -197,7 +199,7 @@ if useDyn then libLocs else- let dflags' = addWay' WayDyn dflags+ let dflags' = dflags { targetWays_ = addWay WayDyn (targetWays_ dflags) } dlibLocs = [ searchPath </> platformHsSOName platform dlibLoc | searchPath <- searchPaths , dlibLoc <- packageHsLibs dflags' pkg
compiler/GHC/Iface/Ext/Ast.hs view
@@ -512,27 +512,12 @@ -} class HasLoc a where- -- ^ defined so that HsImplicitBndrs and HsWildCardBndrs can- -- know what their implicit bindings are scoping over+ -- ^ conveniently calculate locations for things without locations attached loc :: a -> SrcSpan -instance HasLoc thing => HasLoc (TScoped thing) where- loc (TS _ a) = loc a- instance HasLoc thing => HasLoc (PScoped thing) where loc (PS _ _ _ a) = loc a -instance HasLoc (LHsQTyVars GhcRn) where- loc (HsQTvs _ vs) = loc vs--instance HasLoc thing => HasLoc (HsImplicitBndrs a thing) where- loc (HsIB _ a) = loc a- loc _ = noSrcSpan--instance HasLoc thing => HasLoc (HsWildCardBndrs a thing) where- loc (HsWC _ a) = loc a- loc _ = noSrcSpan- instance HasLoc (Located a) where loc (L l _) = l @@ -541,9 +526,11 @@ loc xs = foldl1' combineSrcSpans $ map loc xs instance HasLoc a => HasLoc (FamEqn (GhcPass s) a) where- loc (FamEqn _ a Nothing b _ c) = foldl1' combineSrcSpans [loc a, loc b, loc c]- loc (FamEqn _ a (Just tvs) b _ c) = foldl1' combineSrcSpans- [loc a, loc tvs, loc b, loc c]+ loc (FamEqn _ a outer_bndrs b _ c) = case outer_bndrs of+ HsOuterImplicit{} ->+ foldl1' combineSrcSpans [loc a, loc b, loc c]+ HsOuterExplicit{hso_bndrs = tvs} ->+ foldl1' combineSrcSpans [loc a, loc tvs, loc b, loc c] instance (HasLoc tm, HasLoc ty) => HasLoc (HsArg tm ty) where loc (HsValArg tm) = loc tm@@ -1477,9 +1464,9 @@ instance (ToHie rhs, HasLoc rhs) => ToHie (FamEqn GhcRn rhs) where- toHie fe@(FamEqn _ var tybndrs pats _ rhs) = concatM $+ toHie fe@(FamEqn _ var outer_bndrs pats _ rhs) = concatM $ [ toHie $ C (Decl InstDec $ getRealSpan $ loc fe) var- , toHie $ fmap (tvScopes (ResolvedScopes []) scope) tybndrs+ , toHie $ TVS (ResolvedScopes []) scope outer_bndrs , toHie pats , toHie rhs ]@@ -1517,7 +1504,7 @@ instance ToHie (Located (DerivClauseTys GhcRn)) where toHie (L span dct) = concatM $ makeNode dct span : case dct of- DctSingle _ ty -> [ toHie $ TS (ResolvedScopes[]) ty ]+ DctSingle _ ty -> [ toHie $ TS (ResolvedScopes []) ty ] DctMulti _ tys -> [ toHie $ map (TS (ResolvedScopes [])) tys ] instance ToHie (Located (DerivStrategy GhcRn)) where@@ -1525,7 +1512,7 @@ StockStrategy -> [] AnyclassStrategy -> [] NewtypeStrategy -> []- ViaStrategy s -> [ toHie $ TS (ResolvedScopes []) s ]+ ViaStrategy s -> [ toHie (TS (ResolvedScopes []) s) ] instance ToHie (Located OverlapMode) where toHie (L span _) = locOnly span@@ -1535,11 +1522,15 @@ instance ToHie (Located (ConDecl GhcRn)) where toHie (L span decl) = concatM $ makeNode decl span : case decl of- ConDeclGADT { con_names = names, con_qvars = exp_vars, con_g_ext = imp_vars+ ConDeclGADT { con_names = names, con_bndrs = L outer_bndrs_loc outer_bndrs , con_mb_cxt = ctx, con_g_args = args, con_res_ty = typ } -> [ toHie $ map (C (Decl ConDec $ getRealSpan span)) names- , concatM $ [ bindingsOnly bindings- , toHie $ tvScopes resScope NoScope exp_vars ]+ , case outer_bndrs of+ HsOuterImplicit{hso_ximplicit = imp_vars} ->+ bindingsOnly $ map (C $ TyVarBind (mkScope outer_bndrs_loc) resScope)+ imp_vars+ HsOuterExplicit{hso_bndrs = exp_bndrs} ->+ toHie $ tvScopes resScope NoScope exp_bndrs , toHie ctx , toHie args , toHie typ@@ -1552,7 +1543,6 @@ RecConGADT x -> mkLScope x tyScope = mkLScope typ resScope = ResolvedScopes [ctxScope, rhsScope]- bindings = map (C $ TyVarBind (mkScope (loc exp_vars)) resScope) imp_vars ConDeclH98 { con_name = name, con_ex_tvs = qvars , con_mb_cxt = ctx, con_args = dets } -> [ toHie $ C (Decl ConDec $ getRealSpan span) name@@ -1576,21 +1566,17 @@ , toHie decls ] -instance ( HasLoc thing- , ToHie (TScoped thing)- ) => ToHie (TScoped (HsImplicitBndrs GhcRn thing)) where- toHie (TS sc (HsIB ibrn a)) = concatM $- [ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) ibrn+instance ToHie (TScoped (HsWildCardBndrs GhcRn (Located (HsSigType GhcRn)))) where+ toHie (TS sc (HsWC names a)) = concatM $+ [ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) names , toHie $ TS sc a ] where span = loc a -instance ( HasLoc thing- , ToHie (TScoped thing)- ) => ToHie (TScoped (HsWildCardBndrs GhcRn thing)) where+instance ToHie (TScoped (HsWildCardBndrs GhcRn (Located (HsType GhcRn)))) where toHie (TS sc (HsWC names a)) = concatM $ [ bindingsOnly $ map (C $ TyVarBind (mkScope span) sc) names- , toHie $ TS sc a+ , toHie a ] where span = loc a @@ -1650,18 +1636,26 @@ , toHie $ fmap (C Use) typ ] -instance ToHie (Located (HsType GhcRn)) where- toHie x = toHie $ TS (ResolvedScopes []) x+instance ToHie (TScoped (Located (HsSigType GhcRn))) where+ toHie (TS tsc (L span t@HsSig{sig_bndrs=bndrs,sig_body=body})) = concatM $ makeNode t span :+ [ toHie (TVS tsc (mkScope span) bndrs)+ , toHie body+ ] -instance ToHie (TScoped (Located (HsType GhcRn))) where- toHie (TS tsc (L span t)) = concatM $ makeNode t span : case t of+instance Data flag => ToHie (TVScoped (HsOuterTyVarBndrs flag GhcRn)) where+ toHie (TVS tsc sc bndrs) = case bndrs of+ HsOuterImplicit xs -> bindingsOnly $ map (C $ TyVarBind sc tsc) xs+ HsOuterExplicit _ xs -> toHie $ tvScopes tsc sc xs++instance ToHie (Located (HsType GhcRn)) where+ toHie (L span t) = concatM $ makeNode t span : case t of HsForAllTy _ tele body -> let scope = mkScope $ getLoc body in [ case tele of HsForAllVis { hsf_vis_bndrs = bndrs } ->- toHie $ tvScopes tsc scope bndrs+ toHie $ tvScopes (ResolvedScopes []) scope bndrs HsForAllInvis { hsf_invis_bndrs = bndrs } ->- toHie $ tvScopes tsc scope bndrs+ toHie $ tvScopes (ResolvedScopes []) scope bndrs , toHie body ] HsQualTy _ ctx body ->@@ -1677,7 +1671,7 @@ ] HsAppKindTy _ ty ki -> [ toHie ty- , toHie $ TS (ResolvedScopes []) ki+ , toHie ki ] HsFunTy _ w a b -> [ toHie (arrowToHsType w)
compiler/GHC/Iface/Load.hs view
@@ -6,6 +6,8 @@ {-# LANGUAGE CPP, BangPatterns, RecordWildCards, NondecreasingIndentation #-} {-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE LambdaCase #-}+ {-# OPTIONS_GHC -fno-warn-orphans #-} -- | Loading interface files@@ -103,7 +105,6 @@ import Control.Monad import Control.Exception-import Data.IORef import Data.Map ( toList ) import System.FilePath import System.Directory@@ -432,7 +433,6 @@ ; traceIf (text "Considering whether to load" <+> ppr mod <+> ppr from) -- Check whether we have the interface already- ; dflags <- getDynFlags ; hsc_env <- getTopEnv ; let home_unit = hsc_home_unit hsc_env ; case lookupIfaceByModule hpt (eps_PIT eps) mod of {@@ -550,7 +550,7 @@ ; -- invoke plugins with *full* interface, not final_iface, to ensure -- that plugins have access to declarations, etc.- res <- withPlugins dflags (\p -> interfaceLoadAction p) iface+ res <- withPlugins hsc_env (\p -> interfaceLoadAction p) iface ; return (Succeeded res) }}}} @@ -875,27 +875,35 @@ Failed err -> return (Failed (badIfaceFile file_path err)) Succeeded iface -> return (Succeeded (iface, file_path)) -- Don't forget to fill in the package name...++ -- Indefinite interfaces are ALWAYS non-dynamic.+ checkBuildDynamicToo (Succeeded (iface, _filePath))+ | not (moduleIsDefinite (mi_module iface)) = return ()+ checkBuildDynamicToo (Succeeded (iface, filePath)) = do+ let load_dynamic = do+ dflags <- getDynFlags+ let dynFilePath = addBootSuffix_maybe hi_boot_file+ $ replaceExtension filePath (hiSuf dflags)+ r <- read_file dynFilePath+ case r of+ Succeeded (dynIface, _)+ | mi_mod_hash (mi_final_exts iface) == mi_mod_hash (mi_final_exts dynIface) ->+ return ()+ | otherwise ->+ do traceIf (text "Dynamic hash doesn't match")+ setDynamicTooFailed dflags+ Failed err ->+ do traceIf (text "Failed to load dynamic interface file:" $$ err)+ setDynamicTooFailed dflags+ dflags <- getDynFlags- -- Indefinite interfaces are ALWAYS non-dynamic, and- -- that's OK.- let is_definite_iface = moduleIsDefinite (mi_module iface)- when is_definite_iface $- whenGeneratingDynamicToo dflags $ withDoDynamicToo $ do- let ref = canGenerateDynamicToo dflags- dynFilePath = addBootSuffix_maybe hi_boot_file- $ replaceExtension filePath (dynHiSuf dflags)- r <- read_file dynFilePath- case r of- Succeeded (dynIface, _)- | mi_mod_hash (mi_final_exts iface) == mi_mod_hash (mi_final_exts dynIface) ->- return ()- | otherwise ->- do traceIf (text "Dynamic hash doesn't match")- liftIO $ writeIORef ref False- Failed err ->- do traceIf (text "Failed to load dynamic interface file:" $$ err)- liftIO $ writeIORef ref False+ dynamicTooState dflags >>= \case+ DT_Dont -> return ()+ DT_Failed -> return ()+ DT_Dyn -> load_dynamic+ DT_OK -> withDynamicNow load_dynamic+ checkBuildDynamicToo _ = return () -- | Write interface file
compiler/GHC/Iface/Make.hs view
@@ -193,7 +193,7 @@ } = do let used_names = mkUsedNames tc_result- let pluginModules = map lpModule (cachedPlugins (hsc_dflags hsc_env))+ let pluginModules = map lpModule (hsc_plugins hsc_env) let home_unit = hsc_home_unit hsc_env deps <- mkDependencies (homeUnitId home_unit) (map mi_module pluginModules) tc_result@@ -656,7 +656,7 @@ -- op :: (?x :: String) => a -> a -- and class Baz a where -- op :: (Ord a) => a -> a- (sel_tyvars, rho_ty) = splitForAllTys (idType sel_id)+ (sel_tyvars, rho_ty) = splitForAllTyCoVars (idType sel_id) op_ty = funResultTy rho_ty toDmSpec :: (Name, DefMethSpec Type) -> DefMethSpec IfaceType
compiler/GHC/Iface/Recomp.hs view
@@ -65,6 +65,7 @@ import Data.List (find, sortBy, sort) import qualified Data.Map as Map import qualified Data.Set as Set+import Data.Word (Word64) --Qualified import so we can define a Semigroup instance -- but it doesn't clash with Outputable.<>@@ -275,16 +276,16 @@ -- | Check if any plugins are requesting recompilation checkPlugins :: HscEnv -> ModIface -> IfG RecompileRequired-checkPlugins hsc iface = liftIO $ do- new_fingerprint <- fingerprintPlugins hsc+checkPlugins hsc_env iface = liftIO $ do+ new_fingerprint <- fingerprintPlugins hsc_env let old_fingerprint = mi_plugin_hash (mi_final_exts iface)- pr <- mconcat <$> mapM pluginRecompile' (plugins (hsc_dflags hsc))+ pr <- mconcat <$> mapM pluginRecompile' (plugins hsc_env) return $ pluginRecompileToRecompileRequired old_fingerprint new_fingerprint pr fingerprintPlugins :: HscEnv -> IO Fingerprint fingerprintPlugins hsc_env =- fingerprintPlugins' $ plugins (hsc_dflags hsc_env)+ fingerprintPlugins' $ plugins hsc_env fingerprintPlugins' :: [PluginWithArgs] -> IO Fingerprint fingerprintPlugins' plugins = do@@ -729,6 +730,77 @@ field of a IfaceClsInst): only in the non-binding case should we include the fingerprint; in the binding case we shouldn't since it is merely the name of the thing that we are currently fingerprinting.+++Note [Fingerprinting recursive groups]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++The fingerprinting of a single recursive group is a rather subtle affair, as+seen in #18733.++How not to fingerprint+----------------------++Prior to fixing #18733 we used the following (flawed) scheme to fingerprint a+group in hash environment `hash_env0`:++ 1. extend hash_env0, giving each declaration in the group the fingerprint 0+ 2. use this environment to hash the declarations' ABIs, resulting in+ group_fingerprint+ 3. produce the final hash environment by extending hash_env0, mapping each+ declaration of the group to group_fingerprint++However, this is wrong. Consider, for instance, a program like:++ data A = ARecu B | ABase String deriving (Show)+ data B = BRecu A | BBase Int deriving (Show)++ info :: B+ info = BBase 1++A consequence of (3) is that A and B will have the same fingerprint. This means+that if the user changes `info` to:++ info :: A+ info = ABase "hello"++The program's ABI fingerprint will not change despite `info`'s type, and+therefore ABI, being clearly different.++However, the incorrectness doesn't end there: (1) means that all recursive+occurrences of names within the group will be given the same fingerprint. This+means that the group's fingerprint won't change if we change an occurrence of A+to B.++Surprisingly, this bug (#18733) lurked for many years before being uncovered.++How we now fingerprint+----------------------++As seen above, the fingerprinting function must ensure that a groups+fingerprint captures the structure of within-group occurrences. The scheme that+we use is:++ 0. To ensure determinism, sort the declarations into a stable order by+ declaration name++ 1. Extend hash_env0, giving each declaration in the group a sequential+ fingerprint (e.g. 0, 1, 2, ...).++ 2. Use this environment to hash the declarations' ABIs, resulting in+ group_fingerprint.++ Since we included the sequence number in step (1) programs identical up to+ transposition of recursive occurrences are distinguisable, avoiding the+ second issue mentioned above.++ 3. Produce the final environment by extending hash_env, mapping each+ declaration of the group to the hash of (group_fingerprint, i), where+ i is the position of the declaration in the stable ordering.++ Including i in the hash ensures that the first issue noted above is+ avoided.+ -} -- | Add fingerprints for top-level declarations to a 'ModIface'.@@ -854,18 +926,27 @@ return (env', (hash,decl) : decls_w_hashes) fingerprint_group (local_env, decls_w_hashes) (CyclicSCC abis)- = do let decls = map abiDecl abis+ = do let stable_abis = sortBy cmp_abiNames abis+ stable_decls = map abiDecl stable_abis local_env1 <- foldM extend_hash_env local_env- (zip (repeat fingerprint0) decls)+ (zip (map mkRecFingerprint [0..]) stable_decls)+ -- See Note [Fingerprinting recursive groups] let hash_fn = mk_put_name local_env1 -- pprTrace "fingerprinting" (ppr (map ifName decls) ) $ do- let stable_abis = sortBy cmp_abiNames abis -- put the cycle in a canonical order hash <- computeFingerprint hash_fn stable_abis- let pairs = zip (repeat hash) decls+ let pairs = zip (map (bumpFingerprint hash) [0..]) stable_decls+ -- See Note [Fingerprinting recursive groups] local_env2 <- foldM extend_hash_env local_env pairs return (local_env2, pairs ++ decls_w_hashes) + -- Make a fingerprint from the ordinal position of a binding in its group.+ mkRecFingerprint :: Word64 -> Fingerprint+ mkRecFingerprint i = Fingerprint 0 i++ bumpFingerprint :: Fingerprint -> Word64 -> Fingerprint+ bumpFingerprint fp n = fingerprintFingerprints [ fp, mkRecFingerprint n ]+ -- we have fingerprinted the whole declaration, but we now need -- to assign fingerprints to all the OccNames that it binds, to -- use when referencing those OccNames in later declarations.@@ -884,7 +965,8 @@ -- when calculating fingerprints, we always need to use canonical -- ordering for lists of things. In particular, the mi_deps has various -- lists of modules and suchlike, so put these all in canonical order:- let sorted_deps = sortDependencies (mi_deps iface0)+ let sorted_deps :: Dependencies+ sorted_deps = sortDependencies (mi_deps iface0) -- The export hash of a module depends on the orphan hashes of the -- orphan modules below us in the dependency tree. This is the way@@ -971,7 +1053,8 @@ -- -- put the declarations in a canonical order, sorted by OccName- let sorted_decls = Map.elems $ Map.fromList $+ let sorted_decls :: [(Fingerprint, IfaceDecl)]+ sorted_decls = Map.elems $ Map.fromList $ [(getOccName d, e) | e@(_, d) <- decls_w_hashes] -- the flag hash depends on:@@ -1384,7 +1467,12 @@ -- so there's no guarantee everything is loaded. -- Kind of a heinous hack. initIfaceLoad hsc_env . withException- $ loadInterface (text "lookupVers2") mod ImportBySystem+ $ withoutDynamicNow+ -- For some unknown reason, we need to reset the+ -- dynamicNow bit, otherwise only dynamic+ -- interfaces are looked up and some tests fail+ -- (e.g. T16219).+ $ loadInterface (text "lookupVers2") mod ImportBySystem return $ snd (mi_hash_fn (mi_final_exts iface) occ `orElse` pprPanic "lookupVers1" (ppr mod <+> ppr occ))
compiler/GHC/Iface/Recomp/Flags.hs view
@@ -17,7 +17,7 @@ import GHC.Types.SafeHaskell import GHC.Utils.Fingerprint import GHC.Iface.Recomp.Binary--- import GHC.Utils.Outputable+import GHC.Core.Opt.CallerCC () -- for Binary instances import GHC.Data.EnumSet as EnumSet import System.FilePath (normalise)@@ -61,7 +61,7 @@ ticky = map (`gopt` dflags) [Opt_Ticky, Opt_Ticky_Allocd, Opt_Ticky_LNE, Opt_Ticky_Dyn_Thunk] - flags = ((mainis, safeHs, lang, cpp), (paths, prof, ticky, debugLevel))+ flags = ((mainis, safeHs, lang, cpp), (paths, prof, ticky, debugLevel, callerCcFilters)) in -- pprTrace "flags" (ppr flags) $ computeFingerprint nameio flags
compiler/GHC/Iface/Tidy/StaticPtrTable.hs view
@@ -142,7 +142,8 @@ import GHC.Utils.Panic import GHC.Builtin.Names import GHC.Tc.Utils.Env (lookupGlobal)-import GHC.Runtime.Linker.Types++import GHC.Linker.Types import GHC.Types.Name import GHC.Types.Id
compiler/GHC/IfaceToCore.hs view
@@ -62,6 +62,7 @@ import GHC.Core.ConLike import GHC.Core.DataCon import GHC.Core.Opt.OccurAnal ( occurAnalyseExpr )+import GHC.Core.Ppr import GHC.Unit.External import GHC.Unit.Module@@ -73,6 +74,7 @@ import GHC.Utils.Misc import GHC.Utils.Panic +import GHC.Data.Bag import GHC.Data.Maybe import GHC.Data.FastString import GHC.Data.List.SetOps@@ -1199,13 +1201,11 @@ bndrs' ++ exprsFreeIdsList args') ; case lintExpr dflags in_scope rhs' of- Nothing -> return ()- Just fail_msg -> do { mod <- getIfModule- ; pprPanic "Iface Lint failure"- (vcat [ text "In interface for" <+> ppr mod- , hang doc 2 fail_msg- , ppr name <+> equals <+> ppr rhs'- , text "Iface expr =" <+> ppr rhs ]) } }+ Nothing -> return ()+ Just errs -> liftIO $+ displayLintResults dflags False doc+ (pprCoreExpr rhs')+ (emptyBag, errs) } ; return (bndrs', args', rhs') } ; let mb_tcs = map ifTopFreeName args ; this_mod <- getIfModule@@ -1724,13 +1724,10 @@ in_scope <- get_in_scope dflags <- getDynFlags case lintUnfolding is_compulsory dflags noSrcLoc in_scope core_expr' of- Nothing -> return ()- Just fail_msg -> do { mod <- getIfModule- ; pprPanic "Iface Lint failure"- (vcat [ text "In interface for" <+> ppr mod- , hang doc 2 fail_msg- , ppr name <+> equals <+> ppr core_expr'- , text "Iface expr =" <+> ppr expr ]) }+ Nothing -> return ()+ Just errs -> liftIO $+ displayLintResults dflags False doc+ (pprCoreExpr core_expr') (emptyBag, errs) return core_expr' where doc = ppWhen is_compulsory (text "Compulsory") <+>
+ compiler/GHC/Linker.hs view
@@ -0,0 +1,36 @@+module GHC.Linker+ (+ )+where++import GHC.Prelude ()+ -- We need this dummy dependency for the make build system. Otherwise it+ -- tries to load GHC.Types which may not be built yet.++-- Note [Linkers and loaders]+-- ~~~~~~~~~~~~~~~~~~~~~~~~~~+--+-- Linkers are used to produce linked objects (.so, executables); loaders are+-- used to link in memory (e.g., in GHCi) with the already loaded libraries+-- (ghc-lib, rts, etc.).+--+-- Linking can usually be done with an external linker program ("ld"), but+-- loading is more tricky:+--+-- * Fully dynamic:+-- when GHC is built as a set of dynamic libraries (ghc-lib, rts, etc.)+-- and the modules to load are also compiled for dynamic linking, a+-- solution is to fully rely on external tools:+--+-- 1) link a .so with the external linker+-- 2) load the .so with POSIX's "dlopen"+--+-- * When GHC is built as a static program or when libraries we want to load+-- aren't compiled for dynamic linking, GHC uses its own loader ("runtime+-- linker"). The runtime linker is part of the rts (rts/Linker.c).+--+-- Note that within GHC's codebase we often use the word "linker" to refer to+-- the static object loader in the runtime system.+--+-- Loading can be delegated to an external interpreter ("iserv") when+-- -fexternal-interpreter is used.
+ compiler/GHC/Linker/Dynamic.hs view
@@ -0,0 +1,264 @@+{-# LANGUAGE CPP #-}++-- | Dynamic linker+module GHC.Linker.Dynamic+ ( linkDynLib+ -- * Platform-specifics+ , libmLinkOpts+ )+where++#include "GhclibHsVersions.h"++import GHC.Prelude+import GHC.Platform+import GHC.Platform.Ways++import GHC.Driver.Session++import GHC.Unit.Types+import GHC.Unit.State+import GHC.Utils.Outputable+import GHC.Linker.MacOS+import GHC.Linker.Unit+import GHC.SysTools.Tasks++import qualified Data.Set as Set+import System.FilePath++linkDynLib :: DynFlags -> [String] -> [UnitId] -> IO ()+linkDynLib dflags0 o_files dep_packages+ = do+ let platform = targetPlatform dflags0+ os = platformOS platform++ -- This is a rather ugly hack to fix dynamically linked+ -- GHC on Windows. If GHC is linked with -threaded, then+ -- it links against libHSrts_thr. But if base is linked+ -- against libHSrts, then both end up getting loaded,+ -- and things go wrong. We therefore link the libraries+ -- with the same RTS flags that we link GHC with.+ dflags | OSMinGW32 <- os+ , hostWays `hasWay` WayDyn+ = dflags0 { targetWays_ = hostWays }+ | otherwise+ = dflags0++ verbFlags = getVerbFlags dflags+ o_file = outputFile dflags++ pkgs_with_rts <- getPreloadUnitsAnd+ (initSDocContext dflags defaultUserStyle)+ (unitState dflags)+ (mkHomeUnitFromFlags dflags)+ dep_packages++ let pkg_lib_paths = collectLibraryPaths (ways dflags) pkgs_with_rts+ let pkg_lib_path_opts = concatMap get_pkg_lib_path_opts pkg_lib_paths+ get_pkg_lib_path_opts l+ | ( osElfTarget (platformOS (targetPlatform dflags)) ||+ osMachOTarget (platformOS (targetPlatform dflags)) ) &&+ dynLibLoader dflags == SystemDependent &&+ -- Only if we want dynamic libraries+ WayDyn `Set.member` ways dflags &&+ -- Only use RPath if we explicitly asked for it+ gopt Opt_RPath dflags+ = ["-L" ++ l, "-Xlinker", "-rpath", "-Xlinker", l]+ -- See Note [-Xlinker -rpath vs -Wl,-rpath]+ | otherwise = ["-L" ++ l]++ let lib_paths = libraryPaths dflags+ let lib_path_opts = map ("-L"++) lib_paths++ -- In general we don't want to link our dynamic libs against the RTS+ -- package, because the RTS lib comes in several flavours and we want to be+ -- able to pick the flavour when a binary is linked.+ --+ -- But:+ -- * on Windows we need to link the RTS import lib as Windows does not+ -- allow undefined symbols.+ --+ -- * the RTS library path is still added to the library search path above+ -- in case the RTS is being explicitly linked in (see #3807).+ --+ -- * if -flink-rts is used, we link with the rts.+ --+ let pkgs_without_rts = filter ((/= rtsUnitId) . unitId) pkgs_with_rts+ pkgs+ | OSMinGW32 <- os = pkgs_with_rts+ | gopt Opt_LinkRts dflags = pkgs_with_rts+ | otherwise = pkgs_without_rts+ pkg_link_opts = package_hs_libs ++ extra_libs ++ other_flags+ where (package_hs_libs, extra_libs, other_flags) = collectLinkOpts dflags pkgs++ -- probably _stub.o files+ -- and last temporary shared object file+ let extra_ld_inputs = ldInputs dflags++ -- frameworks+ pkg_framework_opts <- getUnitFrameworkOpts dflags platform+ (map unitId pkgs)+ let framework_opts = getFrameworkOpts dflags platform++ case os of+ OSMinGW32 -> do+ -------------------------------------------------------------+ -- Making a DLL+ -------------------------------------------------------------+ let output_fn = case o_file of+ Just s -> s+ Nothing -> "HSdll.dll"++ runLink dflags (+ map Option verbFlags+ ++ [ Option "-o"+ , FileOption "" output_fn+ , Option "-shared"+ ] +++ [ FileOption "-Wl,--out-implib=" (output_fn ++ ".a")+ | gopt Opt_SharedImplib dflags+ ]+ ++ map (FileOption "") o_files++ -- Permit the linker to auto link _symbol to _imp_symbol+ -- This lets us link against DLLs without needing an "import library"+ ++ [Option "-Wl,--enable-auto-import"]++ ++ extra_ld_inputs+ ++ map Option (+ lib_path_opts+ ++ pkg_lib_path_opts+ ++ pkg_link_opts+ ))+ _ | os == OSDarwin -> do+ -------------------------------------------------------------------+ -- Making a darwin dylib+ -------------------------------------------------------------------+ -- About the options used for Darwin:+ -- -dynamiclib+ -- Apple's way of saying -shared+ -- -undefined dynamic_lookup:+ -- Without these options, we'd have to specify the correct+ -- dependencies for each of the dylibs. Note that we could+ -- (and should) do without this for all libraries except+ -- the RTS; all we need to do is to pass the correct+ -- HSfoo_dyn.dylib files to the link command.+ -- This feature requires Mac OS X 10.3 or later; there is+ -- a similar feature, -flat_namespace -undefined suppress,+ -- which works on earlier versions, but it has other+ -- disadvantages.+ -- -single_module+ -- Build the dynamic library as a single "module", i.e. no+ -- dynamic binding nonsense when referring to symbols from+ -- within the library. The NCG assumes that this option is+ -- specified (on i386, at least).+ -- -install_name+ -- Mac OS/X stores the path where a dynamic library is (to+ -- be) installed in the library itself. It's called the+ -- "install name" of the library. Then any library or+ -- executable that links against it before it's installed+ -- will search for it in its ultimate install location.+ -- By default we set the install name to the absolute path+ -- at build time, but it can be overridden by the+ -- -dylib-install-name option passed to ghc. Cabal does+ -- this.+ -------------------------------------------------------------------++ let output_fn = case o_file of { Just s -> s; Nothing -> "a.out"; }++ instName <- case dylibInstallName dflags of+ Just n -> return n+ Nothing -> return $ "@rpath" `combine` (takeFileName output_fn)+ runLink dflags (+ map Option verbFlags+ ++ [ Option "-dynamiclib"+ , Option "-o"+ , FileOption "" output_fn+ ]+ ++ map Option o_files+ ++ [ Option "-undefined",+ Option "dynamic_lookup",+ Option "-single_module" ]+ ++ (if platformArch platform `elem` [ ArchX86_64, ArchAArch64 ]+ then [ ]+ else [ Option "-Wl,-read_only_relocs,suppress" ])+ ++ [ Option "-install_name", Option instName ]+ ++ map Option lib_path_opts+ ++ extra_ld_inputs+ ++ map Option framework_opts+ ++ map Option pkg_lib_path_opts+ ++ map Option pkg_link_opts+ ++ map Option pkg_framework_opts+ -- dead_strip_dylibs, will remove unused dylibs, and thus save+ -- space in the load commands. The -headerpad is necessary so+ -- that we can inject more @rpath's later for the leftover+ -- libraries in the runInjectRpaths phase below.+ --+ -- See Note [Dynamic linking on macOS]+ ++ [ Option "-Wl,-dead_strip_dylibs", Option "-Wl,-headerpad,8000" ]+ )+ runInjectRPaths dflags pkg_lib_paths output_fn+ _ -> do+ -------------------------------------------------------------------+ -- Making a DSO+ -------------------------------------------------------------------++ let output_fn = case o_file of { Just s -> s; Nothing -> "a.out"; }+ unregisterised = platformUnregisterised (targetPlatform dflags)+ let bsymbolicFlag = -- we need symbolic linking to resolve+ -- non-PIC intra-package-relocations for+ -- performance (where symbolic linking works)+ -- See Note [-Bsymbolic assumptions by GHC]+ ["-Wl,-Bsymbolic" | not unregisterised]++ runLink dflags (+ map Option verbFlags+ ++ libmLinkOpts+ ++ [ Option "-o"+ , FileOption "" output_fn+ ]+ ++ map Option o_files+ ++ [ Option "-shared" ]+ ++ map Option bsymbolicFlag+ -- Set the library soname. We use -h rather than -soname as+ -- Solaris 10 doesn't support the latter:+ ++ [ Option ("-Wl,-h," ++ takeFileName output_fn) ]+ ++ extra_ld_inputs+ ++ map Option lib_path_opts+ ++ map Option pkg_lib_path_opts+ ++ map Option pkg_link_opts+ )++-- | Some platforms require that we explicitly link against @libm@ if any+-- math-y things are used (which we assume to include all programs). See #14022.+libmLinkOpts :: [Option]+libmLinkOpts =+#if defined(HAVE_LIBM)+ [Option "-lm"]+#else+ []+#endif++{-+Note [-Bsymbolic assumptions by GHC]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++GHC has a few assumptions about interaction of relocations in NCG and linker:++1. -Bsymbolic resolves internal references when the shared library is linked,+ which is important for performance.+2. When there is a reference to data in a shared library from the main program,+ the runtime linker relocates the data object into the main program using an+ R_*_COPY relocation.+3. If we used -Bsymbolic, then this results in multiple copies of the data+ object, because some references have already been resolved to point to the+ original instance. This is bad!++We work around [3.] for native compiled code by avoiding the generation of+R_*_COPY relocations.++Unregisterised compiler can't evade R_*_COPY relocations easily thus we disable+-Bsymbolic linking there.++See related tickets: #4210, #15338+-}
+ compiler/GHC/Linker/ExtraObj.hs view
@@ -0,0 +1,260 @@+-----------------------------------------------------------------------------+--+-- GHC Extra object linking code+--+-- (c) The GHC Team 2017+--+-----------------------------------------------------------------------------++module GHC.Linker.ExtraObj+ ( mkExtraObj+ , mkExtraObjToLinkIntoBinary+ , mkNoteObjsToLinkIntoBinary+ , checkLinkInfo+ , getLinkInfo+ , getCompilerInfo+ , ghcLinkInfoSectionName+ , ghcLinkInfoNoteName+ , platformSupportsSavingLinkOpts+ , haveRtsOptsFlags+ )+where++import GHC.Utils.Asm+import GHC.Utils.Error+import GHC.Driver.Session+import GHC.Driver.Ppr+import GHC.Unit.State+import GHC.Platform+import GHC.Utils.Outputable as Outputable+import GHC.Types.SrcLoc ( noSrcSpan )+import GHC.Unit+import GHC.SysTools.Elf+import GHC.Utils.Misc+import GHC.Prelude+import qualified GHC.Data.ShortText as ST++import Control.Monad+import Data.Maybe++import Control.Monad.IO.Class++import GHC.SysTools.FileCleanup+import GHC.SysTools.Tasks+import GHC.SysTools.Info+import GHC.Linker.Unit+import GHC.Linker.MacOS++mkExtraObj :: DynFlags -> Suffix -> String -> IO FilePath+mkExtraObj dflags extn xs+ = do cFile <- newTempName dflags TFL_CurrentModule extn+ oFile <- newTempName dflags TFL_GhcSession "o"+ writeFile cFile xs+ ccInfo <- liftIO $ getCompilerInfo dflags+ runCc Nothing dflags+ ([Option "-c",+ FileOption "" cFile,+ Option "-o",+ FileOption "" oFile]+ ++ if extn /= "s"+ then cOpts+ else asmOpts ccInfo)+ return oFile+ where+ pkgs = unitState dflags++ -- Pass a different set of options to the C compiler depending one whether+ -- we're compiling C or assembler. When compiling C, we pass the usual+ -- set of include directories and PIC flags.+ cOpts = map Option (picCCOpts dflags)+ ++ map (FileOption "-I" . ST.unpack)+ (unitIncludeDirs $ unsafeLookupUnit pkgs rtsUnit)++ -- When compiling assembler code, we drop the usual C options, and if the+ -- compiler is Clang, we add an extra argument to tell Clang to ignore+ -- unused command line options. See trac #11684.+ asmOpts ccInfo =+ if any (ccInfo ==) [Clang, AppleClang, AppleClang51]+ then [Option "-Qunused-arguments"]+ else []++-- When linking a binary, we need to create a C main() function that+-- starts everything off. This used to be compiled statically as part+-- of the RTS, but that made it hard to change the -rtsopts setting,+-- so now we generate and compile a main() stub as part of every+-- binary and pass the -rtsopts setting directly to the RTS (#5373)+--+-- On Windows, when making a shared library we also may need a DllMain.+--+mkExtraObjToLinkIntoBinary :: DynFlags -> IO FilePath+mkExtraObjToLinkIntoBinary dflags = do+ when (gopt Opt_NoHsMain dflags && haveRtsOptsFlags dflags) $+ putLogMsg dflags NoReason SevInfo noSrcSpan+ $ withPprStyle defaultUserStyle+ (text "Warning: -rtsopts and -with-rtsopts have no effect with -no-hs-main." $$+ text " Call hs_init_ghc() from your main() function to set these options.")++ mkExtraObj dflags "c" (showSDoc dflags main)+ where+ main+ | gopt Opt_NoHsMain dflags = Outputable.empty+ | otherwise+ = case ghcLink dflags of+ LinkDynLib -> if platformOS (targetPlatform dflags) == OSMinGW32+ then dllMain+ else Outputable.empty+ _ -> exeMain++ exeMain = vcat [+ text "#include <Rts.h>",+ text "extern StgClosure ZCMain_main_closure;",+ text "int main(int argc, char *argv[])",+ char '{',+ text " RtsConfig __conf = defaultRtsConfig;",+ text " __conf.rts_opts_enabled = "+ <> text (show (rtsOptsEnabled dflags)) <> semi,+ text " __conf.rts_opts_suggestions = "+ <> text (if rtsOptsSuggestions dflags+ then "true"+ else "false") <> semi,+ text "__conf.keep_cafs = "+ <> text (if gopt Opt_KeepCAFs dflags+ then "true"+ else "false") <> semi,+ case rtsOpts dflags of+ Nothing -> Outputable.empty+ Just opts -> text " __conf.rts_opts= " <>+ text (show opts) <> semi,+ text " __conf.rts_hs_main = true;",+ text " return hs_main(argc,argv,&ZCMain_main_closure,__conf);",+ char '}',+ char '\n' -- final newline, to keep gcc happy+ ]++ dllMain = vcat [+ text "#include <Rts.h>",+ text "#include <windows.h>",+ text "#include <stdbool.h>",+ char '\n',+ text "bool",+ text "WINAPI",+ text "DllMain ( HINSTANCE hInstance STG_UNUSED",+ text " , DWORD reason STG_UNUSED",+ text " , LPVOID reserved STG_UNUSED",+ text " )",+ text "{",+ text " return true;",+ text "}",+ char '\n' -- final newline, to keep gcc happy+ ]++-- Write out the link info section into a new assembly file. Previously+-- this was included as inline assembly in the main.c file but this+-- is pretty fragile. gas gets upset trying to calculate relative offsets+-- that span the .note section (notably .text) when debug info is present+mkNoteObjsToLinkIntoBinary :: DynFlags -> [UnitId] -> IO [FilePath]+mkNoteObjsToLinkIntoBinary dflags dep_packages = do+ link_info <- getLinkInfo dflags dep_packages++ if (platformSupportsSavingLinkOpts (platformOS platform ))+ then fmap (:[]) $ mkExtraObj dflags "s" (showSDoc dflags (link_opts link_info))+ else return []++ where+ platform = targetPlatform dflags+ link_opts info = hcat [+ -- "link info" section (see Note [LinkInfo section])+ makeElfNote platform ghcLinkInfoSectionName ghcLinkInfoNoteName 0 info,++ -- ALL generated assembly must have this section to disable+ -- executable stacks. See also+ -- "GHC.CmmToAsm" for another instance+ -- where we need to do this.+ if platformHasGnuNonexecStack platform+ then text ".section .note.GNU-stack,\"\","+ <> sectionType platform "progbits" <> char '\n'+ else Outputable.empty+ ]++-- | Return the "link info" string+--+-- See Note [LinkInfo section]+getLinkInfo :: DynFlags -> [UnitId] -> IO String+getLinkInfo dflags dep_packages = do+ package_link_opts <- getUnitLinkOpts dflags dep_packages+ let unit_state = unitState dflags+ home_unit = mkHomeUnitFromFlags dflags+ ctx = initSDocContext dflags defaultUserStyle+ pkg_frameworks <- if platformUsesFrameworks (targetPlatform dflags)+ then getUnitFrameworks ctx unit_state home_unit dep_packages+ else return []+ let extra_ld_inputs = ldInputs dflags+ let+ link_info = (package_link_opts,+ pkg_frameworks,+ rtsOpts dflags,+ rtsOptsEnabled dflags,+ gopt Opt_NoHsMain dflags,+ map showOpt extra_ld_inputs,+ getOpts dflags opt_l)+ --+ return (show link_info)++platformSupportsSavingLinkOpts :: OS -> Bool+platformSupportsSavingLinkOpts os+ | os == OSSolaris2 = False -- see #5382+ | otherwise = osElfTarget os++-- See Note [LinkInfo section]+ghcLinkInfoSectionName :: String+ghcLinkInfoSectionName = ".debug-ghc-link-info"+ -- if we use the ".debug" prefix, then strip will strip it by default++-- Identifier for the note (see Note [LinkInfo section])+ghcLinkInfoNoteName :: String+ghcLinkInfoNoteName = "GHC link info"++-- Returns 'False' if it was, and we can avoid linking, because the+-- previous binary was linked with "the same options".+checkLinkInfo :: DynFlags -> [UnitId] -> FilePath -> IO Bool+checkLinkInfo dflags pkg_deps exe_file+ | not (platformSupportsSavingLinkOpts (platformOS (targetPlatform dflags)))+ -- ToDo: Windows and OS X do not use the ELF binary format, so+ -- readelf does not work there. We need to find another way to do+ -- this.+ = return False -- conservatively we should return True, but not+ -- linking in this case was the behaviour for a long+ -- time so we leave it as-is.+ | otherwise+ = do+ link_info <- getLinkInfo dflags pkg_deps+ debugTraceMsg dflags 3 $ text ("Link info: " ++ link_info)+ m_exe_link_info <- readElfNoteAsString dflags exe_file+ ghcLinkInfoSectionName ghcLinkInfoNoteName+ let sameLinkInfo = (Just link_info == m_exe_link_info)+ debugTraceMsg dflags 3 $ case m_exe_link_info of+ Nothing -> text "Exe link info: Not found"+ Just s+ | sameLinkInfo -> text ("Exe link info is the same")+ | otherwise -> text ("Exe link info is different: " ++ s)+ return (not sameLinkInfo)++{- Note [LinkInfo section]+ ~~~~~~~~~~~~~~~~~~~~~~~++The "link info" is a string representing the parameters of the link. We save+this information in the binary, and the next time we link, if nothing else has+changed, we use the link info stored in the existing binary to decide whether+to re-link or not.++The "link info" string is stored in a ELF section called ".debug-ghc-link-info"+(see ghcLinkInfoSectionName) with the SHT_NOTE type. For some time, it used to+not follow the specified record-based format (see #11022).++-}++haveRtsOptsFlags :: DynFlags -> Bool+haveRtsOptsFlags dflags =+ isJust (rtsOpts dflags) || case rtsOptsEnabled dflags of+ RtsOptsSafeOnly -> False+ _ -> True
+ compiler/GHC/Linker/Loader.hs view
@@ -0,0 +1,1720 @@+{-# LANGUAGE CPP, TupleSections, RecordWildCards #-}+{-# LANGUAGE BangPatterns #-}++--+-- (c) The University of Glasgow 2002-2006++-- | The loader+--+-- This module deals with the top-level issues of dynamic linking (loading),+-- calling the object-code linker and the byte-code linker where necessary.+module GHC.Linker.Loader+ ( Loader (..)+ , LoaderState (..)+ , initLoaderState+ , uninitializedLoader+ , showLoaderState+ -- * Load & Unload+ , loadExpr+ , loadDecls+ , loadPackages+ , loadModule+ , loadCmdLineLibs+ , loadName+ , unload+ -- * LoadedEnv+ , withExtendedLoadedEnv+ , extendLoadedEnv+ , deleteFromLoadedEnv+ -- * Misc+ , extendLoadedPkgs+ )+where++#include "GhclibHsVersions.h"++import GHC.Prelude++import GHC.Platform+import GHC.Platform.Ways++import GHC.Driver.Phases+import GHC.Driver.Env+import GHC.Driver.Session+import GHC.Driver.Ppr++import GHC.Tc.Utils.Monad++import GHC.Runtime.Interpreter+import GHC.Runtime.Interpreter.Types+import GHCi.RemoteTypes++import GHC.Iface.Load++import GHC.ByteCode.Linker+import GHC.ByteCode.Asm+import GHC.ByteCode.Types++import GHC.SysTools+import GHC.SysTools.FileCleanup++import GHC.Types.Basic+import GHC.Types.Name+import GHC.Types.Name.Env+import GHC.Types.SrcLoc+import GHC.Types.Unique.DSet++import GHC.Utils.Outputable+import GHC.Utils.Panic+import GHC.Utils.Misc+import GHC.Utils.Error++import GHC.Unit.Finder+import GHC.Unit.Module+import GHC.Unit.Module.ModIface+import GHC.Unit.Module.Deps+import GHC.Unit.Home+import GHC.Unit.Home.ModInfo+import GHC.Unit.State as Packages++import qualified GHC.Data.ShortText as ST+import qualified GHC.Data.Maybe as Maybes+import GHC.Data.FastString+import GHC.Data.List.SetOps++import GHC.Linker.MacOS+import GHC.Linker.Dynamic+import GHC.Linker.Types++-- Standard libraries+import Control.Monad++import qualified Data.Set as Set+import Data.Char (isSpace)+import Data.Function ((&))+import Data.IORef+import Data.List (intercalate, isPrefixOf, isSuffixOf, nub, partition)+import Data.Maybe+import Control.Concurrent.MVar+import qualified Control.Monad.Catch as MC++import System.FilePath+import System.Directory+import System.IO.Unsafe+import System.Environment (lookupEnv)++#if defined(mingw32_HOST_OS)+import System.Win32.Info (getSystemDirectory)+#endif++import GHC.Utils.Exception++uninitialised :: a+uninitialised = panic "Loader not initialised"++modifyLS_ :: Loader -> (LoaderState -> IO LoaderState) -> IO ()+modifyLS_ dl f =+ modifyMVar_ (loader_state dl) (fmap pure . f . fromMaybe uninitialised)++modifyLS :: Loader -> (LoaderState -> IO (LoaderState, a)) -> IO a+modifyLS dl f =+ modifyMVar (loader_state dl) (fmapFst pure . f . fromMaybe uninitialised)+ where fmapFst f = fmap (\(x, y) -> (f x, y))++readLS :: Loader -> IO LoaderState+readLS dl =+ (fmap (fromMaybe uninitialised) . readMVar) (loader_state dl)++modifyMbLS_+ :: Loader -> (Maybe LoaderState -> IO (Maybe LoaderState)) -> IO ()+modifyMbLS_ dl f = modifyMVar_ (loader_state dl) f++emptyLS :: LoaderState+emptyLS = LoaderState+ { closure_env = emptyNameEnv+ , itbl_env = emptyNameEnv+ , pkgs_loaded = init_pkgs+ , bcos_loaded = []+ , objs_loaded = []+ , temp_sos = []+ }+ -- Packages that don't need loading, because the compiler+ -- shares them with the interpreted program.+ --+ -- The linker's symbol table is populated with RTS symbols using an+ -- explicit list. See rts/Linker.c for details.+ where init_pkgs = [rtsUnitId]++extendLoadedPkgs :: Loader -> [UnitId] -> IO ()+extendLoadedPkgs dl pkgs =+ modifyLS_ dl $ \s ->+ return s{ pkgs_loaded = pkgs ++ pkgs_loaded s }++extendLoadedEnv :: Loader -> [(Name,ForeignHValue)] -> IO ()+extendLoadedEnv dl new_bindings =+ modifyLS_ dl $ \pls@LoaderState{..} -> do+ let new_ce = extendClosureEnv closure_env new_bindings+ return $! pls{ closure_env = new_ce }+ -- strictness is important for not retaining old copies of the pls++deleteFromLoadedEnv :: Loader -> [Name] -> IO ()+deleteFromLoadedEnv dl to_remove =+ modifyLS_ dl $ \pls -> do+ let ce = closure_env pls+ let new_ce = delListFromNameEnv ce to_remove+ return pls{ closure_env = new_ce }++-- | Load the module containing the given Name and get its associated 'HValue'.+--+-- Throws a 'ProgramError' if loading fails or the name cannot be found.+loadName :: HscEnv -> Name -> IO ForeignHValue+loadName hsc_env name = do+ let dl = hsc_loader hsc_env+ initLoaderState hsc_env+ modifyLS dl $ \pls0 -> do+ pls <- if not (isExternalName name)+ then return pls0+ else do+ (pls', ok) <- loadDependencies hsc_env pls0 noSrcSpan+ [nameModule name]+ if failed ok+ then throwGhcExceptionIO (ProgramError "")+ else return pls'++ case lookupNameEnv (closure_env pls) name of+ Just (_,aa) -> return (pls,aa)+ Nothing -> ASSERT2(isExternalName name, ppr name)+ do let sym_to_find = nameToCLabel name "closure"+ m <- lookupClosure hsc_env (unpackFS sym_to_find)+ r <- case m of+ Just hvref -> mkFinalizedHValue hsc_env hvref+ Nothing -> linkFail "GHC.Linker.Loader.loadName"+ (unpackFS sym_to_find)+ return (pls,r)++loadDependencies :: HscEnv -> LoaderState+ -> SrcSpan -> [Module]+ -> IO (LoaderState, SuccessFlag)+loadDependencies hsc_env pls span needed_mods = do+-- initLoaderState (hsc_dflags hsc_env) dl+ let hpt = hsc_HPT hsc_env+ -- The interpreter and dynamic linker can only handle object code built+ -- the "normal" way, i.e. no non-std ways like profiling or ticky-ticky.+ -- So here we check the build tag: if we're building a non-standard way+ -- then we need to find & link object files built the "normal" way.+ maybe_normal_osuf <- checkNonStdWay hsc_env span++ -- Find what packages and linkables are required+ (lnks, pkgs) <- getLinkDeps hsc_env hpt pls+ maybe_normal_osuf span needed_mods++ -- Link the packages and modules required+ pls1 <- loadPackages' hsc_env pkgs pls+ loadModules hsc_env pls1 lnks+++-- | Temporarily extend the loaded env.++withExtendedLoadedEnv :: (ExceptionMonad m) =>+ Loader -> [(Name,ForeignHValue)] -> m a -> m a+withExtendedLoadedEnv dl new_env action+ = MC.bracket (liftIO $ extendLoadedEnv dl new_env)+ (\_ -> reset_old_env)+ (\_ -> action)+ where+ -- Remember that the linker state might be side-effected+ -- during the execution of the IO action, and we don't want to+ -- lose those changes (we might have linked a new module or+ -- package), so the reset action only removes the names we+ -- added earlier.+ reset_old_env = liftIO $+ modifyLS_ dl $ \pls ->+ let cur = closure_env pls+ new = delListFromNameEnv cur (map fst new_env)+ in return pls{ closure_env = new }+++-- | Display the persistent linker state.+showLoaderState :: Loader -> IO SDoc+showLoaderState dl+ = do pls <- readLS dl+ return $ withPprStyle defaultDumpStyle+ (vcat [text "----- Loader state -----",+ text "Pkgs:" <+> ppr (pkgs_loaded pls),+ text "Objs:" <+> ppr (objs_loaded pls),+ text "BCOs:" <+> ppr (bcos_loaded pls)])+++{- **********************************************************************++ Initialisation++ ********************************************************************* -}++-- | Initialise the dynamic linker. This entails+--+-- a) Calling the C initialisation procedure,+--+-- b) Loading any packages specified on the command line,+--+-- c) Loading any packages specified on the command line, now held in the+-- @-l@ options in @v_Opt_l@,+--+-- d) Loading any @.o\/.dll@ files specified on the command line, now held+-- in @ldInputs@,+--+-- e) Loading any MacOS frameworks.+--+-- NOTE: This function is idempotent; if called more than once, it does+-- nothing. This is useful in Template Haskell, where we call it before+-- trying to link.+--+initLoaderState :: HscEnv -> IO ()+initLoaderState hsc_env = do+ let dl = hsc_loader hsc_env+ modifyMbLS_ dl $ \pls -> do+ case pls of+ Just _ -> return pls+ Nothing -> Just <$> reallyInitLoaderState hsc_env++reallyInitLoaderState :: HscEnv -> IO LoaderState+reallyInitLoaderState hsc_env = do+ -- Initialise the linker state+ let dflags = hsc_dflags hsc_env+ pls0 = emptyLS++ -- (a) initialise the C dynamic linker+ initObjLinker hsc_env++ -- (b) Load packages from the command-line (Note [preload packages])+ pls <- loadPackages' hsc_env (preloadUnits (unitState dflags)) pls0++ -- steps (c), (d) and (e)+ loadCmdLineLibs' hsc_env pls+++loadCmdLineLibs :: HscEnv -> IO ()+loadCmdLineLibs hsc_env = do+ let dl = hsc_loader hsc_env+ initLoaderState hsc_env+ modifyLS_ dl $ \pls ->+ loadCmdLineLibs' hsc_env pls++loadCmdLineLibs' :: HscEnv -> LoaderState -> IO LoaderState+loadCmdLineLibs' hsc_env pls =+ do+ let dflags@(DynFlags { ldInputs = cmdline_ld_inputs+ , libraryPaths = lib_paths_base})+ = hsc_dflags hsc_env++ -- (c) Link libraries from the command-line+ let minus_ls_1 = [ lib | Option ('-':'l':lib) <- cmdline_ld_inputs ]++ -- On Windows we want to add libpthread by default just as GCC would.+ -- However because we don't know the actual name of pthread's dll we+ -- need to defer this to the locateLib call so we can't initialize it+ -- inside of the rts. Instead we do it here to be able to find the+ -- import library for pthreads. See #13210.+ let platform = targetPlatform dflags+ os = platformOS platform+ minus_ls = case os of+ OSMinGW32 -> "pthread" : minus_ls_1+ _ -> minus_ls_1+ -- See Note [Fork/Exec Windows]+ gcc_paths <- getGCCPaths dflags os++ lib_paths_env <- addEnvPaths "LIBRARY_PATH" lib_paths_base++ maybePutStrLn dflags "Search directories (user):"+ maybePutStr dflags (unlines $ map (" "++) lib_paths_env)+ maybePutStrLn dflags "Search directories (gcc):"+ maybePutStr dflags (unlines $ map (" "++) gcc_paths)++ libspecs+ <- mapM (locateLib hsc_env False lib_paths_env gcc_paths) minus_ls++ -- (d) Link .o files from the command-line+ classified_ld_inputs <- mapM (classifyLdInput dflags)+ [ f | FileOption _ f <- cmdline_ld_inputs ]++ -- (e) Link any MacOS frameworks+ let platform = targetPlatform dflags+ let (framework_paths, frameworks) =+ if platformUsesFrameworks platform+ then (frameworkPaths dflags, cmdlineFrameworks dflags)+ else ([],[])++ -- Finally do (c),(d),(e)+ let cmdline_lib_specs = catMaybes classified_ld_inputs+ ++ libspecs+ ++ map Framework frameworks+ if null cmdline_lib_specs+ then return pls+ else do+ -- Add directories to library search paths, this only has an effect+ -- on Windows. On Unix OSes this function is a NOP.+ let all_paths = let paths = takeDirectory (pgm_c dflags)+ : framework_paths+ ++ lib_paths_base+ ++ [ takeDirectory dll | DLLPath dll <- libspecs ]+ in nub $ map normalise paths+ let lib_paths = nub $ lib_paths_base ++ gcc_paths+ all_paths_env <- addEnvPaths "LD_LIBRARY_PATH" all_paths+ pathCache <- mapM (addLibrarySearchPath hsc_env) all_paths_env++ let merged_specs = mergeStaticObjects cmdline_lib_specs+ pls1 <- foldM (preloadLib hsc_env lib_paths framework_paths) pls+ merged_specs++ maybePutStr dflags "final link ... "+ ok <- resolveObjs hsc_env++ -- DLLs are loaded, reset the search paths+ mapM_ (removeLibrarySearchPath hsc_env) $ reverse pathCache++ if succeeded ok then maybePutStrLn dflags "done"+ else throwGhcExceptionIO (ProgramError "linking extra libraries/objects failed")++ return pls1++-- | Merge runs of consecutive of 'Objects'. This allows for resolution of+-- cyclic symbol references when dynamically linking. Specifically, we link+-- together all of the static objects into a single shared object, avoiding+-- the issue we saw in #13786.+mergeStaticObjects :: [LibrarySpec] -> [LibrarySpec]+mergeStaticObjects specs = go [] specs+ where+ go :: [FilePath] -> [LibrarySpec] -> [LibrarySpec]+ go accum (Objects objs : rest) = go (objs ++ accum) rest+ go accum@(_:_) rest = Objects (reverse accum) : go [] rest+ go [] (spec:rest) = spec : go [] rest+ go [] [] = []++{- Note [preload packages]++Why do we need to preload packages from the command line? This is an+explanation copied from #2437:++I tried to implement the suggestion from #3560, thinking it would be+easy, but there are two reasons we link in packages eagerly when they+are mentioned on the command line:++ * So that you can link in extra object files or libraries that+ depend on the packages. e.g. ghc -package foo -lbar where bar is a+ C library that depends on something in foo. So we could link in+ foo eagerly if and only if there are extra C libs or objects to+ link in, but....++ * Haskell code can depend on a C function exported by a package, and+ the normal dependency tracking that TH uses can't know about these+ dependencies. The test ghcilink004 relies on this, for example.++I conclude that we need two -package flags: one that says "this is a+package I want to make available", and one that says "this is a+package I want to link in eagerly". Would that be too complicated for+users?+-}++classifyLdInput :: DynFlags -> FilePath -> IO (Maybe LibrarySpec)+classifyLdInput dflags f+ | isObjectFilename platform f = return (Just (Objects [f]))+ | isDynLibFilename platform f = return (Just (DLLPath f))+ | otherwise = do+ putLogMsg dflags NoReason SevInfo noSrcSpan+ $ withPprStyle defaultUserStyle+ (text ("Warning: ignoring unrecognised input `" ++ f ++ "'"))+ return Nothing+ where platform = targetPlatform dflags++preloadLib+ :: HscEnv -> [String] -> [String] -> LoaderState+ -> LibrarySpec -> IO LoaderState+preloadLib hsc_env lib_paths framework_paths pls lib_spec = do+ maybePutStr dflags ("Loading object " ++ showLS lib_spec ++ " ... ")+ case lib_spec of+ Objects static_ishs -> do+ (b, pls1) <- preload_statics lib_paths static_ishs+ maybePutStrLn dflags (if b then "done" else "not found")+ return pls1++ Archive static_ish -> do+ b <- preload_static_archive lib_paths static_ish+ maybePutStrLn dflags (if b then "done" else "not found")+ return pls++ DLL dll_unadorned -> do+ maybe_errstr <- loadDLL hsc_env (platformSOName platform dll_unadorned)+ case maybe_errstr of+ Nothing -> maybePutStrLn dflags "done"+ Just mm | platformOS platform /= OSDarwin ->+ preloadFailed mm lib_paths lib_spec+ Just mm | otherwise -> do+ -- As a backup, on Darwin, try to also load a .so file+ -- since (apparently) some things install that way - see+ -- ticket #8770.+ let libfile = ("lib" ++ dll_unadorned) <.> "so"+ err2 <- loadDLL hsc_env libfile+ case err2 of+ Nothing -> maybePutStrLn dflags "done"+ Just _ -> preloadFailed mm lib_paths lib_spec+ return pls++ DLLPath dll_path -> do+ do maybe_errstr <- loadDLL hsc_env dll_path+ case maybe_errstr of+ Nothing -> maybePutStrLn dflags "done"+ Just mm -> preloadFailed mm lib_paths lib_spec+ return pls++ Framework framework ->+ if platformUsesFrameworks (targetPlatform dflags)+ then do maybe_errstr <- loadFramework hsc_env framework_paths framework+ case maybe_errstr of+ Nothing -> maybePutStrLn dflags "done"+ Just mm -> preloadFailed mm framework_paths lib_spec+ return pls+ else throwGhcExceptionIO (ProgramError "preloadLib Framework")++ where+ dflags = hsc_dflags hsc_env++ platform = targetPlatform dflags++ preloadFailed :: String -> [String] -> LibrarySpec -> IO ()+ preloadFailed sys_errmsg paths spec+ = do maybePutStr dflags "failed.\n"+ throwGhcExceptionIO $+ CmdLineError (+ "user specified .o/.so/.DLL could not be loaded ("+ ++ sys_errmsg ++ ")\nWhilst trying to load: "+ ++ showLS spec ++ "\nAdditional directories searched:"+ ++ (if null paths then " (none)" else+ intercalate "\n" (map (" "++) paths)))++ -- Not interested in the paths in the static case.+ preload_statics _paths names+ = do b <- or <$> mapM doesFileExist names+ if not b then return (False, pls)+ else if hostIsDynamic+ then do pls1 <- dynLoadObjs hsc_env pls names+ return (True, pls1)+ else do mapM_ (loadObj hsc_env) names+ return (True, pls)++ preload_static_archive _paths name+ = do b <- doesFileExist name+ if not b then return False+ else do if hostIsDynamic+ then throwGhcExceptionIO $+ CmdLineError dynamic_msg+ else loadArchive hsc_env name+ return True+ where+ dynamic_msg = unlines+ [ "User-specified static library could not be loaded ("+ ++ name ++ ")"+ , "Loading static libraries is not supported in this configuration."+ , "Try using a dynamic library instead."+ ]+++{- **********************************************************************++ Link a byte-code expression++ ********************************************************************* -}++-- | Load a single expression, /including/ first loading packages and+-- modules that this expression depends on.+--+-- Raises an IO exception ('ProgramError') if it can't find a compiled+-- version of the dependents to load.+--+loadExpr :: HscEnv -> SrcSpan -> UnlinkedBCO -> IO ForeignHValue+loadExpr hsc_env span root_ul_bco+ = do {+ -- Initialise the linker (if it's not been done already)+ ; initLoaderState hsc_env++ -- Extract the Loader value for passing into required places+ ; let dl = hsc_loader hsc_env++ -- Take lock for the actual work.+ ; modifyLS dl $ \pls0 -> do {++ -- Load the packages and modules required+ ; (pls, ok) <- loadDependencies hsc_env pls0 span needed_mods+ ; if failed ok then+ throwGhcExceptionIO (ProgramError "")+ else do {++ -- Load the expression itself+ let ie = itbl_env pls+ ce = closure_env pls++ -- Load the necessary packages and linkables++ ; let nobreakarray = error "no break array"+ bco_ix = mkNameEnv [(unlinkedBCOName root_ul_bco, 0)]+ ; resolved <- linkBCO hsc_env ie ce bco_ix nobreakarray root_ul_bco+ ; [root_hvref] <- createBCOs hsc_env [resolved]+ ; fhv <- mkFinalizedHValue hsc_env root_hvref+ ; return (pls, fhv)+ }}}+ where+ free_names = uniqDSetToList (bcoFreeNames root_ul_bco)++ needed_mods :: [Module]+ needed_mods = [ nameModule n | n <- free_names,+ isExternalName n, -- Names from other modules+ not (isWiredInName n) -- Exclude wired-in names+ ] -- (see note below)+ -- Exclude wired-in names because we may not have read+ -- their interface files, so getLinkDeps will fail+ -- All wired-in names are in the base package, which we link+ -- by default, so we can safely ignore them here.++dieWith :: DynFlags -> SrcSpan -> MsgDoc -> IO a+dieWith dflags span msg = throwGhcExceptionIO (ProgramError (showSDoc dflags (mkLocMessage SevFatal span msg)))+++checkNonStdWay :: HscEnv -> SrcSpan -> IO (Maybe FilePath)+checkNonStdWay hsc_env srcspan+ | Just (ExternalInterp {}) <- hsc_interp hsc_env = return Nothing+ -- with -fexternal-interpreter we load the .o files, whatever way+ -- they were built. If they were built for a non-std way, then+ -- we will use the appropriate variant of the iserv binary to load them.++ | hostFullWays == targetFullWays = return Nothing+ -- Only if we are compiling with the same ways as GHC is built+ -- with, can we dynamically load those object files. (see #3604)++ | objectSuf (hsc_dflags hsc_env) == normalObjectSuffix && not (null targetFullWays)+ = failNonStd (hsc_dflags hsc_env) srcspan++ | otherwise = return (Just (hostWayTag ++ "o"))+ where+ targetFullWays = fullWays (ways (hsc_dflags hsc_env))+ hostWayTag = case waysTag hostFullWays of+ "" -> ""+ tag -> tag ++ "_"++normalObjectSuffix :: String+normalObjectSuffix = phaseInputExt StopLn++failNonStd :: DynFlags -> SrcSpan -> IO (Maybe FilePath)+failNonStd dflags srcspan = dieWith dflags srcspan $+ text "Cannot load" <+> compWay <+>+ text "objects when GHC is built" <+> ghciWay $$+ text "To fix this, either:" $$+ text " (1) Use -fexternal-interpreter, or" $$+ text " (2) Build the program twice: once" <+>+ ghciWay <> text ", and then" $$+ text " with" <+> compWay <+>+ text "using -osuf to set a different object file suffix."+ where compWay+ | WayDyn `elem` ways dflags = text "-dynamic"+ | WayProf `elem` ways dflags = text "-prof"+ | otherwise = text "normal"+ ghciWay+ | hostIsDynamic = text "with -dynamic"+ | hostIsProfiled = text "with -prof"+ | otherwise = text "the normal way"++getLinkDeps :: HscEnv -> HomePackageTable+ -> LoaderState+ -> Maybe FilePath -- replace object suffices?+ -> SrcSpan -- for error messages+ -> [Module] -- If you need these+ -> IO ([Linkable], [UnitId]) -- ... then link these first+-- Fails with an IO exception if it can't find enough files++getLinkDeps hsc_env hpt pls replace_osuf span mods+-- Find all the packages and linkables that a set of modules depends on+ = do {+ -- 1. Find the dependent home-pkg-modules/packages from each iface+ -- (omitting modules from the interactive package, which is already linked)+ ; (mods_s, pkgs_s) <- follow_deps (filterOut isInteractiveModule mods)+ emptyUniqDSet emptyUniqDSet;++ ; let {+ -- 2. Exclude ones already linked+ -- Main reason: avoid findModule calls in get_linkable+ mods_needed = mods_s `minusList` linked_mods ;+ pkgs_needed = pkgs_s `minusList` pkgs_loaded pls ;++ linked_mods = map (moduleName.linkableModule)+ (objs_loaded pls ++ bcos_loaded pls) }++ -- 3. For each dependent module, find its linkable+ -- This will either be in the HPT or (in the case of one-shot+ -- compilation) we may need to use maybe_getFileLinkable+ ; let { osuf = objectSuf dflags }+ ; lnks_needed <- mapM (get_linkable osuf) mods_needed++ ; return (lnks_needed, pkgs_needed) }+ where+ dflags = hsc_dflags hsc_env++ -- The ModIface contains the transitive closure of the module dependencies+ -- within the current package, *except* for boot modules: if we encounter+ -- a boot module, we have to find its real interface and discover the+ -- dependencies of that. Hence we need to traverse the dependency+ -- tree recursively. See bug #936, testcase ghci/prog007.+ follow_deps :: [Module] -- modules to follow+ -> UniqDSet ModuleName -- accum. module dependencies+ -> UniqDSet UnitId -- accum. package dependencies+ -> IO ([ModuleName], [UnitId]) -- result+ follow_deps [] acc_mods acc_pkgs+ = return (uniqDSetToList acc_mods, uniqDSetToList acc_pkgs)+ follow_deps (mod:mods) acc_mods acc_pkgs+ = do+ mb_iface <- initIfaceCheck (text "getLinkDeps") hsc_env $+ loadInterface msg mod (ImportByUser NotBoot)+ iface <- case mb_iface of+ Maybes.Failed err -> throwGhcExceptionIO (ProgramError (showSDoc dflags err))+ Maybes.Succeeded iface -> return iface++ when (mi_boot iface == IsBoot) $ link_boot_mod_error mod++ let+ pkg = moduleUnit mod+ deps = mi_deps iface+ home_unit = hsc_home_unit hsc_env++ pkg_deps = dep_pkgs deps+ (boot_deps, mod_deps) = flip partitionWith (dep_mods deps) $+ \ (GWIB { gwib_mod = m, gwib_isBoot = is_boot }) ->+ m & case is_boot of+ IsBoot -> Left+ NotBoot -> Right++ boot_deps' = filter (not . (`elementOfUniqDSet` acc_mods)) boot_deps+ acc_mods' = addListToUniqDSet acc_mods (moduleName mod : mod_deps)+ acc_pkgs' = addListToUniqDSet acc_pkgs $ map fst pkg_deps+ --+ if not (isHomeUnit home_unit pkg)+ then follow_deps mods acc_mods (addOneToUniqDSet acc_pkgs' (toUnitId pkg))+ else follow_deps (map (mkHomeModule home_unit) boot_deps' ++ mods)+ acc_mods' acc_pkgs'+ where+ msg = text "need to link module" <+> ppr mod <+>+ text "due to use of Template Haskell"+++ link_boot_mod_error mod =+ throwGhcExceptionIO (ProgramError (showSDoc dflags (+ text "module" <+> ppr mod <+>+ text "cannot be linked; it is only available as a boot module")))++ no_obj :: Outputable a => a -> IO b+ no_obj mod = dieWith dflags span $+ text "cannot find object file for module " <>+ quotes (ppr mod) $$+ while_linking_expr++ while_linking_expr = text "while linking an interpreted expression"++ -- This one is a build-system bug++ get_linkable osuf mod_name -- A home-package module+ | Just mod_info <- lookupHpt hpt mod_name+ = adjust_linkable (Maybes.expectJust "getLinkDeps" (hm_linkable mod_info))+ | otherwise+ = do -- It's not in the HPT because we are in one shot mode,+ -- so use the Finder to get a ModLocation...+ mb_stuff <- findHomeModule hsc_env mod_name+ case mb_stuff of+ Found loc mod -> found loc mod+ _ -> no_obj mod_name+ where+ found loc mod = do {+ -- ...and then find the linkable for it+ mb_lnk <- findObjectLinkableMaybe mod loc ;+ case mb_lnk of {+ Nothing -> no_obj mod ;+ Just lnk -> adjust_linkable lnk+ }}++ adjust_linkable lnk+ | Just new_osuf <- replace_osuf = do+ new_uls <- mapM (adjust_ul new_osuf)+ (linkableUnlinked lnk)+ return lnk{ linkableUnlinked=new_uls }+ | otherwise =+ return lnk++ adjust_ul new_osuf (DotO file) = do+ MASSERT(osuf `isSuffixOf` file)+ let file_base = fromJust (stripExtension osuf file)+ new_file = file_base <.> new_osuf+ ok <- doesFileExist new_file+ if (not ok)+ then dieWith dflags span $+ text "cannot find object file "+ <> quotes (text new_file) $$ while_linking_expr+ else return (DotO new_file)+ adjust_ul _ (DotA fp) = panic ("adjust_ul DotA " ++ show fp)+ adjust_ul _ (DotDLL fp) = panic ("adjust_ul DotDLL " ++ show fp)+ adjust_ul _ l@(BCOs {}) = return l++++{- **********************************************************************++ Loading a Decls statement++ ********************************************************************* -}++loadDecls :: HscEnv -> SrcSpan -> CompiledByteCode -> IO ()+loadDecls hsc_env span cbc@CompiledByteCode{..} = do+ -- Initialise the linker (if it's not been done already)+ initLoaderState hsc_env++ -- Extract the Loader for passing into required places+ let dl = hsc_loader hsc_env++ -- Take lock for the actual work.+ modifyLS_ dl $ \pls0 -> do+ -- Link the packages and modules required+ (pls, ok) <- loadDependencies hsc_env pls0 span needed_mods+ if failed ok+ then throwGhcExceptionIO (ProgramError "")+ else do+ -- Link the expression itself+ let ie = plusNameEnv (itbl_env pls) bc_itbls+ ce = closure_env pls++ -- Link the necessary packages and linkables+ new_bindings <- linkSomeBCOs hsc_env ie ce [cbc]+ nms_fhvs <- makeForeignNamedHValueRefs hsc_env new_bindings+ let pls2 = pls { closure_env = extendClosureEnv ce nms_fhvs+ , itbl_env = ie }+ return pls2+ where+ free_names = uniqDSetToList $+ foldr (unionUniqDSets . bcoFreeNames) emptyUniqDSet bc_bcos++ needed_mods :: [Module]+ needed_mods = [ nameModule n | n <- free_names,+ isExternalName n, -- Names from other modules+ not (isWiredInName n) -- Exclude wired-in names+ ] -- (see note below)+ -- Exclude wired-in names because we may not have read+ -- their interface files, so getLinkDeps will fail+ -- All wired-in names are in the base package, which we link+ -- by default, so we can safely ignore them here.++{- **********************************************************************++ Loading a single module++ ********************************************************************* -}++loadModule :: HscEnv -> Module -> IO ()+loadModule hsc_env mod = do+ initLoaderState hsc_env+ let dl = hsc_loader hsc_env+ modifyLS_ dl $ \pls -> do+ (pls', ok) <- loadDependencies hsc_env pls noSrcSpan [mod]+ if failed ok+ then throwGhcExceptionIO (ProgramError "could not load module")+ else return pls'++{- **********************************************************************++ Link some linkables+ The linkables may consist of a mixture of+ byte-code modules and object modules++ ********************************************************************* -}++loadModules :: HscEnv -> LoaderState -> [Linkable] -> IO (LoaderState, SuccessFlag)+loadModules hsc_env pls linkables+ = mask_ $ do -- don't want to be interrupted by ^C in here++ let (objs, bcos) = partition isObjectLinkable+ (concatMap partitionLinkable linkables)++ -- Load objects first; they can't depend on BCOs+ (pls1, ok_flag) <- loadObjects hsc_env pls objs++ if failed ok_flag then+ return (pls1, Failed)+ else do+ pls2 <- dynLinkBCOs hsc_env pls1 bcos+ return (pls2, Succeeded)+++-- HACK to support f-x-dynamic in the interpreter; no other purpose+partitionLinkable :: Linkable -> [Linkable]+partitionLinkable li+ = let li_uls = linkableUnlinked li+ li_uls_obj = filter isObject li_uls+ li_uls_bco = filter isInterpretable li_uls+ in+ case (li_uls_obj, li_uls_bco) of+ (_:_, _:_) -> [li {linkableUnlinked=li_uls_obj},+ li {linkableUnlinked=li_uls_bco}]+ _ -> [li]++findModuleLinkable_maybe :: [Linkable] -> Module -> Maybe Linkable+findModuleLinkable_maybe lis mod+ = case [LM time nm us | LM time nm us <- lis, nm == mod] of+ [] -> Nothing+ [li] -> Just li+ _ -> pprPanic "findModuleLinkable" (ppr mod)++linkableInSet :: Linkable -> [Linkable] -> Bool+linkableInSet l objs_loaded =+ case findModuleLinkable_maybe objs_loaded (linkableModule l) of+ Nothing -> False+ Just m -> linkableTime l == linkableTime m+++{- **********************************************************************++ The object-code linker++ ********************************************************************* -}++-- | Load the object files and link them+--+-- If the interpreter uses dynamic-linking, build a shared library and load it.+-- Otherwise, use the RTS linker.+loadObjects :: HscEnv -> LoaderState -> [Linkable]+ -> IO (LoaderState, SuccessFlag)+loadObjects hsc_env pls objs = do+ let (objs_loaded', new_objs) = rmDupLinkables (objs_loaded pls) objs+ pls1 = pls { objs_loaded = objs_loaded' }+ unlinkeds = concatMap linkableUnlinked new_objs+ wanted_objs = map nameOfObject unlinkeds++ if interpreterDynamic (hscInterp hsc_env)+ then do pls2 <- dynLoadObjs hsc_env pls1 wanted_objs+ return (pls2, Succeeded)+ else do mapM_ (loadObj hsc_env) wanted_objs++ -- Link them all together+ ok <- resolveObjs hsc_env++ -- If resolving failed, unload all our+ -- object modules and carry on+ if succeeded ok then+ return (pls1, Succeeded)+ else do+ pls2 <- unload_wkr hsc_env [] pls1+ return (pls2, Failed)+++-- | Create a shared library containing the given object files and load it.+dynLoadObjs :: HscEnv -> LoaderState -> [FilePath] -> IO LoaderState+dynLoadObjs _ pls [] = return pls+dynLoadObjs hsc_env pls@LoaderState{..} objs = do+ let dflags = hsc_dflags hsc_env+ let platform = targetPlatform dflags+ let minus_ls = [ lib | Option ('-':'l':lib) <- ldInputs dflags ]+ let minus_big_ls = [ lib | Option ('-':'L':lib) <- ldInputs dflags ]+ (soFile, libPath , libName) <-+ newTempLibName dflags TFL_CurrentModule (platformSOExt platform)+ let+ dflags2 = dflags {+ -- We don't want the original ldInputs in+ -- (they're already linked in), but we do want+ -- to link against previous dynLoadObjs+ -- libraries if there were any, so that the linker+ -- can resolve dependencies when it loads this+ -- library.+ ldInputs =+ concatMap (\l -> [ Option ("-l" ++ l) ])+ (nub $ snd <$> temp_sos)+ ++ concatMap (\lp -> Option ("-L" ++ lp)+ : if gopt Opt_RPath dflags+ then [ Option "-Xlinker"+ , Option "-rpath"+ , Option "-Xlinker"+ , Option lp ]+ else [])+ (nub $ fst <$> temp_sos)+ ++ concatMap+ (\lp -> Option ("-L" ++ lp)+ : if gopt Opt_RPath dflags+ then [ Option "-Xlinker"+ , Option "-rpath"+ , Option "-Xlinker"+ , Option lp ]+ else [])+ minus_big_ls+ -- See Note [-Xlinker -rpath vs -Wl,-rpath]+ ++ map (\l -> Option ("-l" ++ l)) minus_ls,+ -- Add -l options and -L options from dflags.+ --+ -- When running TH for a non-dynamic way, we still+ -- need to make -l flags to link against the dynamic+ -- libraries, so we need to add WayDyn to ways.+ --+ -- Even if we're e.g. profiling, we still want+ -- the vanilla dynamic libraries, so we set the+ -- ways / build tag to be just WayDyn.+ targetWays_ = Set.singleton WayDyn,+ outputFile_ = Just soFile+ }+ -- link all "loaded packages" so symbols in those can be resolved+ -- Note: We are loading packages with local scope, so to see the+ -- symbols in this link we must link all loaded packages again.+ linkDynLib dflags2 objs pkgs_loaded++ -- if we got this far, extend the lifetime of the library file+ changeTempFilesLifetime dflags TFL_GhcSession [soFile]+ m <- loadDLL hsc_env soFile+ case m of+ Nothing -> return $! pls { temp_sos = (libPath, libName) : temp_sos }+ Just err -> linkFail msg err+ where+ msg = "GHC.Linker.Loader.dynLoadObjs: Loading temp shared object failed"++rmDupLinkables :: [Linkable] -- Already loaded+ -> [Linkable] -- New linkables+ -> ([Linkable], -- New loaded set (including new ones)+ [Linkable]) -- New linkables (excluding dups)+rmDupLinkables already ls+ = go already [] ls+ where+ go already extras [] = (already, extras)+ go already extras (l:ls)+ | linkableInSet l already = go already extras ls+ | otherwise = go (l:already) (l:extras) ls++{- **********************************************************************++ The byte-code linker++ ********************************************************************* -}+++dynLinkBCOs :: HscEnv -> LoaderState -> [Linkable] -> IO LoaderState+dynLinkBCOs hsc_env pls bcos = do++ let (bcos_loaded', new_bcos) = rmDupLinkables (bcos_loaded pls) bcos+ pls1 = pls { bcos_loaded = bcos_loaded' }+ unlinkeds :: [Unlinked]+ unlinkeds = concatMap linkableUnlinked new_bcos++ cbcs :: [CompiledByteCode]+ cbcs = map byteCodeOfObject unlinkeds+++ ies = map bc_itbls cbcs+ gce = closure_env pls+ final_ie = foldr plusNameEnv (itbl_env pls) ies++ names_and_refs <- linkSomeBCOs hsc_env final_ie gce cbcs++ -- We only want to add the external ones to the ClosureEnv+ let (to_add, to_drop) = partition (isExternalName.fst) names_and_refs++ -- Immediately release any HValueRefs we're not going to add+ freeHValueRefs hsc_env (map snd to_drop)+ -- Wrap finalizers on the ones we want to keep+ new_binds <- makeForeignNamedHValueRefs hsc_env to_add++ return pls1 { closure_env = extendClosureEnv gce new_binds,+ itbl_env = final_ie }++-- Link a bunch of BCOs and return references to their values+linkSomeBCOs :: HscEnv+ -> ItblEnv+ -> ClosureEnv+ -> [CompiledByteCode]+ -> IO [(Name,HValueRef)]+ -- The returned HValueRefs are associated 1-1 with+ -- the incoming unlinked BCOs. Each gives the+ -- value of the corresponding unlinked BCO++linkSomeBCOs hsc_env ie ce mods = foldr fun do_link mods []+ where+ fun CompiledByteCode{..} inner accum =+ case bc_breaks of+ Nothing -> inner ((panic "linkSomeBCOs: no break array", bc_bcos) : accum)+ Just mb -> withForeignRef (modBreaks_flags mb) $ \breakarray ->+ inner ((breakarray, bc_bcos) : accum)++ do_link [] = return []+ do_link mods = do+ let flat = [ (breakarray, bco) | (breakarray, bcos) <- mods, bco <- bcos ]+ names = map (unlinkedBCOName . snd) flat+ bco_ix = mkNameEnv (zip names [0..])+ resolved <- sequence [ linkBCO hsc_env ie ce bco_ix breakarray bco+ | (breakarray, bco) <- flat ]+ hvrefs <- createBCOs hsc_env resolved+ return (zip names hvrefs)++-- | Useful to apply to the result of 'linkSomeBCOs'+makeForeignNamedHValueRefs+ :: HscEnv -> [(Name,HValueRef)] -> IO [(Name,ForeignHValue)]+makeForeignNamedHValueRefs hsc_env bindings =+ mapM (\(n, hvref) -> (n,) <$> mkFinalizedHValue hsc_env hvref) bindings++{- **********************************************************************++ Unload some object modules++ ********************************************************************* -}++-- ---------------------------------------------------------------------------+-- | Unloading old objects ready for a new compilation sweep.+--+-- The compilation manager provides us with a list of linkables that it+-- considers \"stable\", i.e. won't be recompiled this time around. For+-- each of the modules current linked in memory,+--+-- * if the linkable is stable (and it's the same one -- the user may have+-- recompiled the module on the side), we keep it,+--+-- * otherwise, we unload it.+--+-- * we also implicitly unload all temporary bindings at this point.+--+unload :: HscEnv+ -> [Linkable] -- ^ The linkables to *keep*.+ -> IO ()+unload hsc_env linkables+ = mask_ $ do -- mask, so we're safe from Ctrl-C in here++ -- Initialise the linker (if it's not been done already)+ initLoaderState hsc_env++ -- Extract Loader for passing into required places+ let dl = hsc_loader hsc_env++ new_pls+ <- modifyLS dl $ \pls -> do+ pls1 <- unload_wkr hsc_env linkables pls+ return (pls1, pls1)++ let dflags = hsc_dflags hsc_env+ debugTraceMsg dflags 3 $+ text "unload: retaining objs" <+> ppr (objs_loaded new_pls)+ debugTraceMsg dflags 3 $+ text "unload: retaining bcos" <+> ppr (bcos_loaded new_pls)+ return ()++unload_wkr :: HscEnv+ -> [Linkable] -- stable linkables+ -> LoaderState+ -> IO LoaderState+-- Does the core unload business+-- (the wrapper blocks exceptions and deals with the LS get and put)++unload_wkr hsc_env keep_linkables pls@LoaderState{..} = do+ -- NB. careful strictness here to avoid keeping the old LS when+ -- we're unloading some code. -fghci-leak-check with the tests in+ -- testsuite/ghci can detect space leaks here.++ let (objs_to_keep, bcos_to_keep) = partition isObjectLinkable keep_linkables++ discard keep l = not (linkableInSet l keep)++ (objs_to_unload, remaining_objs_loaded) =+ partition (discard objs_to_keep) objs_loaded+ (bcos_to_unload, remaining_bcos_loaded) =+ partition (discard bcos_to_keep) bcos_loaded++ mapM_ unloadObjs objs_to_unload+ mapM_ unloadObjs bcos_to_unload++ -- If we unloaded any object files at all, we need to purge the cache+ -- of lookupSymbol results.+ when (not (null (objs_to_unload +++ filter (not . null . linkableObjs) bcos_to_unload))) $+ purgeLookupSymbolCache hsc_env++ let !bcos_retained = mkModuleSet $ map linkableModule remaining_bcos_loaded++ -- Note that we want to remove all *local*+ -- (i.e. non-isExternal) names too (these are the+ -- temporary bindings from the command line).+ keep_name :: (Name, a) -> Bool+ keep_name (n,_) = isExternalName n &&+ nameModule n `elemModuleSet` bcos_retained++ itbl_env' = filterNameEnv keep_name itbl_env+ closure_env' = filterNameEnv keep_name closure_env++ !new_pls = pls { itbl_env = itbl_env',+ closure_env = closure_env',+ bcos_loaded = remaining_bcos_loaded,+ objs_loaded = remaining_objs_loaded }++ return new_pls+ where+ unloadObjs :: Linkable -> IO ()+ unloadObjs lnk+ -- The RTS's PEi386 linker currently doesn't support unloading.+ | isWindowsHost = return ()++ | hostIsDynamic = return ()+ -- We don't do any cleanup when linking objects with the+ -- dynamic linker. Doing so introduces extra complexity for+ -- not much benefit.++ | otherwise+ = mapM_ (unloadObj hsc_env) [f | DotO f <- linkableUnlinked lnk]+ -- The components of a BCO linkable may contain+ -- dot-o files. Which is very confusing.+ --+ -- But the BCO parts can be unlinked just by+ -- letting go of them (plus of course depopulating+ -- the symbol table which is done in the main body)++{- **********************************************************************++ Loading packages++ ********************************************************************* -}++data LibrarySpec+ = Objects [FilePath] -- Full path names of set of .o files, including trailing .o+ -- We allow batched loading to ensure that cyclic symbol+ -- references can be resolved (see #13786).+ -- For dynamic objects only, try to find the object+ -- file in all the directories specified in+ -- v_Library_paths before giving up.++ | Archive FilePath -- Full path name of a .a file, including trailing .a++ | DLL String -- "Unadorned" name of a .DLL/.so+ -- e.g. On unix "qt" denotes "libqt.so"+ -- On Windows "burble" denotes "burble.DLL" or "libburble.dll"+ -- loadDLL is platform-specific and adds the lib/.so/.DLL+ -- suffixes platform-dependently++ | DLLPath FilePath -- Absolute or relative pathname to a dynamic library+ -- (ends with .dll or .so).++ | Framework String -- Only used for darwin, but does no harm++instance Outputable LibrarySpec where+ ppr (Objects objs) = text "Objects" <+> ppr objs+ ppr (Archive a) = text "Archive" <+> text a+ ppr (DLL s) = text "DLL" <+> text s+ ppr (DLLPath f) = text "DLLPath" <+> text f+ ppr (Framework s) = text "Framework" <+> text s++-- If this package is already part of the GHCi binary, we'll already+-- have the right DLLs for this package loaded, so don't try to+-- load them again.+--+-- But on Win32 we must load them 'again'; doing so is a harmless no-op+-- as far as the loader is concerned, but it does initialise the list+-- of DLL handles that rts/Linker.c maintains, and that in turn is+-- used by lookupSymbol. So we must call addDLL for each library+-- just to get the DLL handle into the list.+partOfGHCi :: [PackageName]+partOfGHCi+ | isWindowsHost || isDarwinHost = []+ | otherwise = map (PackageName . mkFastString)+ ["base", "template-haskell", "editline"]++showLS :: LibrarySpec -> String+showLS (Objects nms) = "(static) [" ++ intercalate ", " nms ++ "]"+showLS (Archive nm) = "(static archive) " ++ nm+showLS (DLL nm) = "(dynamic) " ++ nm+showLS (DLLPath nm) = "(dynamic) " ++ nm+showLS (Framework nm) = "(framework) " ++ nm++-- | Load exactly the specified packages, and their dependents (unless of+-- course they are already loaded). The dependents are loaded+-- automatically, and it doesn't matter what order you specify the input+-- packages.+--+loadPackages :: HscEnv -> [UnitId] -> IO ()+-- NOTE: in fact, since each module tracks all the packages it depends on,+-- we don't really need to use the package-config dependencies.+--+-- However we do need the package-config stuff (to find aux libs etc),+-- and following them lets us load libraries in the right order, which+-- perhaps makes the error message a bit more localised if we get a link+-- failure. So the dependency walking code is still here.++loadPackages hsc_env new_pkgs = do+ -- It's probably not safe to try to load packages concurrently, so we take+ -- a lock.+ initLoaderState hsc_env+ let dl = hsc_loader hsc_env+ modifyLS_ dl $ \pls ->+ loadPackages' hsc_env new_pkgs pls++loadPackages' :: HscEnv -> [UnitId] -> LoaderState -> IO LoaderState+loadPackages' hsc_env new_pks pls = do+ pkgs' <- link (pkgs_loaded pls) new_pks+ return $! pls { pkgs_loaded = pkgs' }+ where+ dflags = hsc_dflags hsc_env+ pkgstate = unitState dflags++ link :: [UnitId] -> [UnitId] -> IO [UnitId]+ link pkgs new_pkgs =+ foldM link_one pkgs new_pkgs++ link_one pkgs new_pkg+ | new_pkg `elem` pkgs -- Already linked+ = return pkgs++ | Just pkg_cfg <- lookupUnitId pkgstate new_pkg+ = do { -- Link dependents first+ pkgs' <- link pkgs (unitDepends pkg_cfg)+ -- Now link the package itself+ ; loadPackage hsc_env pkg_cfg+ ; return (new_pkg : pkgs') }++ | otherwise+ = throwGhcExceptionIO (CmdLineError ("unknown package: " ++ unpackFS (unitIdFS new_pkg)))+++loadPackage :: HscEnv -> UnitInfo -> IO ()+loadPackage hsc_env pkg+ = do+ let dflags = hsc_dflags hsc_env+ platform = targetPlatform dflags+ is_dyn = interpreterDynamic (hscInterp hsc_env)+ dirs | is_dyn = map ST.unpack $ Packages.unitLibraryDynDirs pkg+ | otherwise = map ST.unpack $ Packages.unitLibraryDirs pkg++ let hs_libs = map ST.unpack $ Packages.unitLibraries pkg+ -- The FFI GHCi import lib isn't needed as+ -- GHC.Linker.Loader + rts/Linker.c link the+ -- interpreted references to FFI to the compiled FFI.+ -- We therefore filter it out so that we don't get+ -- duplicate symbol errors.+ hs_libs' = filter ("HSffi" /=) hs_libs++ -- Because of slight differences between the GHC dynamic linker and+ -- the native system linker some packages have to link with a+ -- different list of libraries when using GHCi. Examples include: libs+ -- that are actually gnu ld scripts, and the possibility that the .a+ -- libs do not exactly match the .so/.dll equivalents. So if the+ -- package file provides an "extra-ghci-libraries" field then we use+ -- that instead of the "extra-libraries" field.+ extdeplibs = map ST.unpack (if null (Packages.unitExtDepLibsGhc pkg)+ then Packages.unitExtDepLibsSys pkg+ else Packages.unitExtDepLibsGhc pkg)+ linkerlibs = [ lib | '-':'l':lib <- (map ST.unpack $ Packages.unitLinkerOptions pkg) ]+ extra_libs = extdeplibs ++ linkerlibs++ -- See Note [Fork/Exec Windows]+ gcc_paths <- getGCCPaths dflags (platformOS platform)+ dirs_env <- addEnvPaths "LIBRARY_PATH" dirs++ hs_classifieds+ <- mapM (locateLib hsc_env True dirs_env gcc_paths) hs_libs'+ extra_classifieds+ <- mapM (locateLib hsc_env False dirs_env gcc_paths) extra_libs+ let classifieds = hs_classifieds ++ extra_classifieds++ -- Complication: all the .so's must be loaded before any of the .o's.+ let known_dlls = [ dll | DLLPath dll <- classifieds ]+ dlls = [ dll | DLL dll <- classifieds ]+ objs = [ obj | Objects objs <- classifieds+ , obj <- objs ]+ archs = [ arch | Archive arch <- classifieds ]++ -- Add directories to library search paths+ let dll_paths = map takeDirectory known_dlls+ all_paths = nub $ map normalise $ dll_paths ++ dirs+ all_paths_env <- addEnvPaths "LD_LIBRARY_PATH" all_paths+ pathCache <- mapM (addLibrarySearchPath hsc_env) all_paths_env++ maybePutSDoc dflags+ (text "Loading unit " <> pprUnitInfoForUser pkg <> text " ... ")++ -- See comments with partOfGHCi+#if defined(CAN_LOAD_DLL)+ when (unitPackageName pkg `notElem` partOfGHCi) $ do+ loadFrameworks hsc_env platform pkg+ -- See Note [Crash early load_dyn and locateLib]+ -- Crash early if can't load any of `known_dlls`+ mapM_ (load_dyn hsc_env True) known_dlls+ -- For remaining `dlls` crash early only when there is surely+ -- no package's DLL around ... (not is_dyn)+ mapM_ (load_dyn hsc_env (not is_dyn) . platformSOName platform) dlls+#endif+ -- After loading all the DLLs, we can load the static objects.+ -- Ordering isn't important here, because we do one final link+ -- step to resolve everything.+ mapM_ (loadObj hsc_env) objs+ mapM_ (loadArchive hsc_env) archs++ maybePutStr dflags "linking ... "+ ok <- resolveObjs hsc_env++ -- DLLs are loaded, reset the search paths+ -- Import libraries will be loaded via loadArchive so only+ -- reset the DLL search path after all archives are loaded+ -- as well.+ mapM_ (removeLibrarySearchPath hsc_env) $ reverse pathCache++ if succeeded ok+ then maybePutStrLn dflags "done."+ else let errmsg = text "unable to load unit `"+ <> pprUnitInfoForUser pkg <> text "'"+ in throwGhcExceptionIO (InstallationError (showSDoc dflags errmsg))++{-+Note [Crash early load_dyn and locateLib]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+If a package is "normal" (exposes it's code from more than zero Haskell+modules, unlike e.g. that in ghcilink004) and is built "dyn" way, then+it has it's code compiled and linked into the DLL, which GHCi linker picks+when loading the package's code (see the big comment in the beginning of+`locateLib`).++When loading DLLs, GHCi linker simply calls the system's `dlopen` or+`LoadLibrary` APIs. This is quite different from the case when GHCi linker+loads an object file or static library. When loading an object file or static+library GHCi linker parses them and resolves all symbols "manually".+These object file or static library may reference some external symbols+defined in some external DLLs. And GHCi should know which these+external DLLs are.++But when GHCi loads a DLL, it's the *system* linker who manages all+the necessary dependencies, and it is able to load this DLL not having+any extra info. Thus we don't *have to* crash in this case even if we+are unable to load any supposed dependencies explicitly.++Suppose during GHCi session a client of the package wants to+`foreign import` a symbol which isn't exposed by the package DLL, but+is exposed by such an external (dependency) DLL.+If the DLL isn't *explicitly* loaded because `load_dyn` failed to do+this, then the client code eventually crashes because the GHCi linker+isn't able to locate this symbol (GHCi linker maintains a list of+explicitly loaded DLLs it looks into when trying to find a symbol).++This is why we still should try to load all the dependency DLLs+even though we know that the system linker loads them implicitly when+loading the package DLL.++Why we still keep the `crash_early` opportunity then not allowing such+a permissive behaviour for any DLLs? Well, we, perhaps, improve a user+experience in some cases slightly.++But if it happens there exist other corner cases where our current+usage of `crash_early` flag is overly restrictive, we may lift the+restriction very easily.+-}++-- we have already searched the filesystem; the strings passed to load_dyn+-- can be passed directly to loadDLL. They are either fully-qualified+-- ("/usr/lib/libfoo.so"), or unqualified ("libfoo.so"). In the latter case,+-- loadDLL is going to search the system paths to find the library.+load_dyn :: HscEnv -> Bool -> FilePath -> IO ()+load_dyn hsc_env crash_early dll = do+ r <- loadDLL hsc_env dll+ case r of+ Nothing -> return ()+ Just err ->+ if crash_early+ then cmdLineErrorIO err+ else let dflags = hsc_dflags hsc_env in+ when (wopt Opt_WarnMissedExtraSharedLib dflags)+ $ putLogMsg dflags+ (Reason Opt_WarnMissedExtraSharedLib) SevWarning+ noSrcSpan $ withPprStyle defaultUserStyle (note err)+ where+ note err = vcat $ map text+ [ err+ , "It's OK if you don't want to use symbols from it directly."+ , "(the package DLL is loaded by the system linker"+ , " which manages dependencies by itself)." ]++loadFrameworks :: HscEnv -> Platform -> UnitInfo -> IO ()+loadFrameworks hsc_env platform pkg+ = when (platformUsesFrameworks platform) $ mapM_ load frameworks+ where+ fw_dirs = map ST.unpack $ Packages.unitExtDepFrameworkDirs pkg+ frameworks = map ST.unpack $ Packages.unitExtDepFrameworks pkg++ load fw = do r <- loadFramework hsc_env fw_dirs fw+ case r of+ Nothing -> return ()+ Just err -> cmdLineErrorIO ("can't load framework: "+ ++ fw ++ " (" ++ err ++ ")" )++-- Try to find an object file for a given library in the given paths.+-- If it isn't present, we assume that addDLL in the RTS can find it,+-- which generally means that it should be a dynamic library in the+-- standard system search path.+-- For GHCi we tend to prefer dynamic libraries over static ones as+-- they are easier to load and manage, have less overhead.+locateLib :: HscEnv -> Bool -> [FilePath] -> [FilePath] -> String+ -> IO LibrarySpec+locateLib hsc_env is_hs lib_dirs gcc_dirs lib+ | not is_hs+ -- For non-Haskell libraries (e.g. gmp, iconv):+ -- first look in library-dirs for a dynamic library (on User paths only)+ -- (libfoo.so)+ -- then try looking for import libraries on Windows (on User paths only)+ -- (.dll.a, .lib)+ -- first look in library-dirs for a dynamic library (on GCC paths only)+ -- (libfoo.so)+ -- then check for system dynamic libraries (e.g. kernel32.dll on windows)+ -- then try looking for import libraries on Windows (on GCC paths only)+ -- (.dll.a, .lib)+ -- then look in library-dirs for a static library (libfoo.a)+ -- then look in library-dirs and inplace GCC for a dynamic library (libfoo.so)+ -- then try looking for import libraries on Windows (.dll.a, .lib)+ -- then look in library-dirs and inplace GCC for a static library (libfoo.a)+ -- then try "gcc --print-file-name" to search gcc's search path+ -- for a dynamic library (#5289)+ -- otherwise, assume loadDLL can find it+ --+ -- The logic is a bit complicated, but the rationale behind it is that+ -- loading a shared library for us is O(1) while loading an archive is+ -- O(n). Loading an import library is also O(n) so in general we prefer+ -- shared libraries because they are simpler and faster.+ --+ =+#if defined(CAN_LOAD_DLL)+ findDll user `orElse`+#endif+ tryImpLib user `orElse`+#if defined(CAN_LOAD_DLL)+ findDll gcc `orElse`+ findSysDll `orElse`+#endif+ tryImpLib gcc `orElse`+ findArchive `orElse`+ tryGcc `orElse`+ assumeDll++ | loading_dynamic_hs_libs -- search for .so libraries first.+ = findHSDll `orElse`+ findDynObject `orElse`+ assumeDll++ | otherwise+ -- use HSfoo.{o,p_o} if it exists, otherwise fallback to libHSfoo{,_p}.a+ = findObject `orElse`+ findArchive `orElse`+ assumeDll++ where+ dflags = hsc_dflags hsc_env+ interp = hscInterp hsc_env+ dirs = lib_dirs ++ gcc_dirs+ gcc = False+ user = True++ obj_file+ | is_hs && loading_profiled_hs_libs = lib <.> "p_o"+ | otherwise = lib <.> "o"+ dyn_obj_file = lib <.> "dyn_o"+ arch_files = [ "lib" ++ lib ++ lib_tag <.> "a"+ , lib <.> "a" -- native code has no lib_tag+ , "lib" ++ lib, lib+ ]+ lib_tag = if is_hs && loading_profiled_hs_libs then "_p" else ""++ loading_profiled_hs_libs = interpreterProfiled interp+ loading_dynamic_hs_libs = interpreterDynamic interp++ import_libs = [ lib <.> "lib" , "lib" ++ lib <.> "lib"+ , "lib" ++ lib <.> "dll.a", lib <.> "dll.a"+ ]++ hs_dyn_lib_name = lib ++ '-':programName dflags ++ projectVersion dflags+ hs_dyn_lib_file = platformHsSOName platform hs_dyn_lib_name++ so_name = platformSOName platform lib+ lib_so_name = "lib" ++ so_name+ dyn_lib_file = case (arch, os) of+ (ArchX86_64, OSSolaris2) -> "64" </> so_name+ _ -> so_name++ findObject = liftM (fmap $ Objects . (:[])) $ findFile dirs obj_file+ findDynObject = liftM (fmap $ Objects . (:[])) $ findFile dirs dyn_obj_file+ findArchive = let local name = liftM (fmap Archive) $ findFile dirs name+ in apply (map local arch_files)+ findHSDll = liftM (fmap DLLPath) $ findFile dirs hs_dyn_lib_file+ findDll re = let dirs' = if re == user then lib_dirs else gcc_dirs+ in liftM (fmap DLLPath) $ findFile dirs' dyn_lib_file+ findSysDll = fmap (fmap $ DLL . dropExtension . takeFileName) $+ findSystemLibrary hsc_env so_name+ tryGcc = let search = searchForLibUsingGcc dflags+ dllpath = liftM (fmap DLLPath)+ short = dllpath $ search so_name lib_dirs+ full = dllpath $ search lib_so_name lib_dirs+ gcc name = liftM (fmap Archive) $ search name lib_dirs+ files = import_libs ++ arch_files+ dlls = [short, full]+ archives = map gcc files+ in apply $+#if defined(CAN_LOAD_DLL)+ dlls +++#endif+ archives+ tryImpLib re = case os of+ OSMinGW32 ->+ let dirs' = if re == user then lib_dirs else gcc_dirs+ implib name = liftM (fmap Archive) $+ findFile dirs' name+ in apply (map implib import_libs)+ _ -> return Nothing++ -- TH Makes use of the interpreter so this failure is not obvious.+ -- So we are nice and warn/inform users why we fail before we do.+ -- But only for haskell libraries, as C libraries don't have a+ -- profiling/non-profiling distinction to begin with.+ assumeDll+ | is_hs+ , not loading_dynamic_hs_libs+ , interpreterProfiled interp+ = do+ warningMsg dflags+ (text "Interpreter failed to load profiled static library" <+> text lib <> char '.' $$+ text " \tTrying dynamic library instead. If this fails try to rebuild" <+>+ text "libraries with profiling support.")+ return (DLL lib)+ | otherwise = return (DLL lib)+ infixr `orElse`+ f `orElse` g = f >>= maybe g return++ apply :: [IO (Maybe a)] -> IO (Maybe a)+ apply [] = return Nothing+ apply (x:xs) = do x' <- x+ if isJust x'+ then return x'+ else apply xs++ platform = targetPlatform dflags+ arch = platformArch platform+ os = platformOS platform++searchForLibUsingGcc :: DynFlags -> String -> [FilePath] -> IO (Maybe FilePath)+searchForLibUsingGcc dflags so dirs = do+ -- GCC does not seem to extend the library search path (using -L) when using+ -- --print-file-name. So instead pass it a new base location.+ str <- askLd dflags (map (FileOption "-B") dirs+ ++ [Option "--print-file-name", Option so])+ let file = case lines str of+ [] -> ""+ l:_ -> l+ if (file == so)+ then return Nothing+ else do b <- doesFileExist file -- file could be a folder (see #16063)+ return (if b then Just file else Nothing)++-- | Retrieve the list of search directory GCC and the System use to find+-- libraries and components. See Note [Fork/Exec Windows].+getGCCPaths :: DynFlags -> OS -> IO [FilePath]+getGCCPaths dflags os+ = case os of+ OSMinGW32 ->+ do gcc_dirs <- getGccSearchDirectory dflags "libraries"+ sys_dirs <- getSystemDirectories+ return $ nub $ gcc_dirs ++ sys_dirs+ _ -> return []++-- | Cache for the GCC search directories as this can't easily change+-- during an invocation of GHC. (Maybe with some env. variable but we'll)+-- deal with that highly unlikely scenario then.+{-# NOINLINE gccSearchDirCache #-}+gccSearchDirCache :: IORef [(String, [String])]+gccSearchDirCache = unsafePerformIO $ newIORef []++-- Note [Fork/Exec Windows]+-- ~~~~~~~~~~~~~~~~~~~~~~~~+-- fork/exec is expensive on Windows, for each time we ask GCC for a library we+-- have to eat the cost of af least 3 of these: gcc -> real_gcc -> cc1.+-- So instead get a list of location that GCC would search and use findDirs+-- which hopefully is written in an optimized mannor to take advantage of+-- caching. At the very least we remove the overhead of the fork/exec and waits+-- which dominate a large percentage of startup time on Windows.+getGccSearchDirectory :: DynFlags -> String -> IO [FilePath]+getGccSearchDirectory dflags key = do+ cache <- readIORef gccSearchDirCache+ case lookup key cache of+ Just x -> return x+ Nothing -> do+ str <- askLd dflags [Option "--print-search-dirs"]+ let line = dropWhile isSpace str+ name = key ++ ": ="+ if null line+ then return []+ else do let val = split $ find name line+ dirs <- filterM doesDirectoryExist val+ modifyIORef' gccSearchDirCache ((key, dirs):)+ return val+ where split :: FilePath -> [FilePath]+ split r = case break (==';') r of+ (s, [] ) -> [s]+ (s, (_:xs)) -> s : split xs++ find :: String -> String -> String+ find r x = let lst = lines x+ val = filter (r `isPrefixOf`) lst+ in if null val+ then []+ else case break (=='=') (head val) of+ (_ , []) -> []+ (_, (_:xs)) -> xs++-- | Get a list of system search directories, this to alleviate pressure on+-- the findSysDll function.+getSystemDirectories :: IO [FilePath]+#if defined(mingw32_HOST_OS)+getSystemDirectories = fmap (:[]) getSystemDirectory+#else+getSystemDirectories = return []+#endif++-- | Merge the given list of paths with those in the environment variable+-- given. If the variable does not exist then just return the identity.+addEnvPaths :: String -> [String] -> IO [String]+addEnvPaths name list+ = do -- According to POSIX (chapter 8.3) a zero-length prefix means current+ -- working directory. Replace empty strings in the env variable with+ -- `working_dir` (see also #14695).+ working_dir <- getCurrentDirectory+ values <- lookupEnv name+ case values of+ Nothing -> return list+ Just arr -> return $ list ++ splitEnv working_dir arr+ where+ splitEnv :: FilePath -> String -> [String]+ splitEnv working_dir value =+ case break (== envListSep) value of+ (x, [] ) ->+ [if null x then working_dir else x]+ (x, (_:xs)) ->+ (if null x then working_dir else x) : splitEnv working_dir xs+#if defined(mingw32_HOST_OS)+ envListSep = ';'+#else+ envListSep = ':'+#endif++-- ----------------------------------------------------------------------------+-- Loading a dynamic library (dlopen()-ish on Unix, LoadLibrary-ish on Win32)+++{- **********************************************************************++ Helper functions++ ********************************************************************* -}++maybePutSDoc :: DynFlags -> SDoc -> IO ()+maybePutSDoc dflags s+ = when (verbosity dflags > 1) $+ putLogMsg dflags+ NoReason+ SevInteractive+ noSrcSpan+ $ withPprStyle defaultUserStyle s++maybePutStr :: DynFlags -> String -> IO ()+maybePutStr dflags s = maybePutSDoc dflags (text s)++maybePutStrLn :: DynFlags -> String -> IO ()+maybePutStrLn dflags s = maybePutStr dflags (s ++ "\n")
+ compiler/GHC/Linker/MacOS.hs view
@@ -0,0 +1,183 @@+module GHC.Linker.MacOS+ ( runInjectRPaths+ , getUnitFrameworks+ , getUnitFrameworkOpts+ , getUnitFrameworkPath+ , getFrameworkOpts+ , loadFramework+ )+where++import GHC.Prelude+import GHC.Platform++import GHC.Driver.Session+import GHC.Driver.Env++import GHC.Unit.Types+import GHC.Unit.State+import GHC.Unit.Home++import GHC.SysTools.Tasks++import GHC.Runtime.Interpreter (loadDLL)++import GHC.Utils.Outputable+import GHC.Utils.Exception+import GHC.Utils.Misc (ordNub )++import qualified GHC.Data.ShortText as ST++import Data.List+import Control.Monad (join, forM, filterM)+import System.Directory (doesFileExist, getHomeDirectory)+import System.FilePath ((</>), (<.>))++-- | On macOS we rely on the linkers @-dead_strip_dylibs@ flag to remove unused+-- libraries from the dynamic library. We do this to reduce the number of load+-- commands that end up in the dylib, and has been limited to 32K (32768) since+-- macOS Sierra (10.14).+--+-- @-dead_strip_dylibs@ does not dead strip @-rpath@ entries, as such passing+-- @-l@ and @-rpath@ to the linker will result in the unnecesasry libraries not+-- being included in the load commands, however the @-rpath@ entries are all+-- forced to be included. This can lead to 100s of @-rpath@ entries being+-- included when only a handful of libraries end up being truely linked.+--+-- Thus after building the library, we run a fixup phase where we inject the+-- @-rpath@ for each found library (in the given library search paths) into the+-- dynamic library through @-add_rpath@.+--+-- See Note [Dynamic linking on macOS]+runInjectRPaths :: DynFlags -> [FilePath] -> FilePath -> IO ()+runInjectRPaths dflags lib_paths dylib = do+ info <- lines <$> askOtool dflags Nothing [Option "-L", Option dylib]+ -- filter the output for only the libraries. And then drop the @rpath prefix.+ let libs = fmap (drop 7) $ filter (isPrefixOf "@rpath") $ fmap (head.words) $ info+ -- find any pre-existing LC_PATH items+ info <- fmap words.lines <$> askOtool dflags Nothing [Option "-l", Option dylib]+ let paths = concatMap f info+ where f ("path":p:_) = [p]+ f _ = []+ lib_paths' = [ p | p <- lib_paths, not (p `elem` paths) ]+ -- only find those rpaths, that aren't already in the library.+ rpaths <- nub . sort . join <$> forM libs (\f -> filterM (\l -> doesFileExist (l </> f)) lib_paths')+ -- inject the rpaths+ case rpaths of+ [] -> return ()+ _ -> runInstallNameTool dflags $ map Option $ "-add_rpath":(intersperse "-add_rpath" rpaths) ++ [dylib]++getUnitFrameworkOpts :: DynFlags -> Platform -> [UnitId] -> IO [String]+getUnitFrameworkOpts dflags platform dep_packages+ | platformUsesFrameworks platform = do+ pkg_framework_path_opts <- do+ pkg_framework_paths <- getUnitFrameworkPath+ (initSDocContext dflags defaultUserStyle)+ (unitState dflags)+ (mkHomeUnitFromFlags dflags)+ dep_packages+ return $ map ("-F" ++) pkg_framework_paths++ pkg_framework_opts <- do+ pkg_frameworks <- getUnitFrameworks+ (initSDocContext dflags defaultUserStyle)+ (unitState dflags)+ (mkHomeUnitFromFlags dflags)+ dep_packages+ return $ concat [ ["-framework", fw] | fw <- pkg_frameworks ]++ return (pkg_framework_path_opts ++ pkg_framework_opts)++ | otherwise = return []++getFrameworkOpts :: DynFlags -> Platform -> [String]+getFrameworkOpts dflags platform+ | platformUsesFrameworks platform = framework_path_opts ++ framework_opts+ | otherwise = []+ where+ framework_paths = frameworkPaths dflags+ framework_path_opts = map ("-F" ++) framework_paths++ frameworks = cmdlineFrameworks dflags+ -- reverse because they're added in reverse order from the cmd line:+ framework_opts = concat [ ["-framework", fw]+ | fw <- reverse frameworks ]+++-- | Find all the package framework paths in these and the preload packages+getUnitFrameworkPath :: SDocContext -> UnitState -> HomeUnit -> [UnitId] -> IO [String]+getUnitFrameworkPath ctx unit_state home_unit pkgs = do+ ps <- getPreloadUnitsAnd ctx unit_state home_unit pkgs+ return $ map ST.unpack (ordNub (filter (not . ST.null) (concatMap unitExtDepFrameworkDirs ps)))++-- | Find all the package frameworks in these and the preload packages+getUnitFrameworks :: SDocContext -> UnitState -> HomeUnit -> [UnitId] -> IO [String]+getUnitFrameworks ctx unit_state home_unit pkgs = do+ ps <- getPreloadUnitsAnd ctx unit_state home_unit pkgs+ return $ map ST.unpack (concatMap unitExtDepFrameworks ps)+++{-+Note [macOS Big Sur dynamic libraries]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++macOS Big Sur makes the following change to how frameworks are shipped+with the OS:++> New in macOS Big Sur 11 beta, the system ships with a built-in+> dynamic linker cache of all system-provided libraries. As part of+> this change, copies of dynamic libraries are no longer present on+> the filesystem. Code that attempts to check for dynamic library+> presence by looking for a file at a path or enumerating a directory+> will fail. Instead, check for library presence by attempting to+> dlopen() the path, which will correctly check for the library in the+> cache. (62986286)++(https://developer.apple.com/documentation/macos-release-notes/macos-big-sur-11-beta-release-notes/)++Therefore, the previous method of checking whether a library exists+before attempting to load it makes GHC.Linker.MacOS.loadFramework+fail to find frameworks installed at /System/Library/Frameworks.+Instead, any attempt to load a framework at runtime, such as by+passing -framework OpenGL to runghc or running code loading such a+framework with GHCi, fails with a 'not found' message.++GHC.Linker.MacOS.loadFramework now opportunistically loads the+framework libraries without checking for their existence first,+failing only if all attempts to load a given framework from any of the+various possible locations fail. See also #18446, which this change+addresses.+-}++-- Darwin / MacOS X only: load a framework+-- a framework is a dynamic library packaged inside a directory of the same+-- name. They are searched for in different paths than normal libraries.+loadFramework :: HscEnv -> [FilePath] -> FilePath -> IO (Maybe String)+loadFramework hsc_env extraPaths rootname+ = do { either_dir <- tryIO getHomeDirectory+ ; let homeFrameworkPath = case either_dir of+ Left _ -> []+ Right dir -> [dir </> "Library/Frameworks"]+ ps = extraPaths ++ homeFrameworkPath ++ defaultFrameworkPaths+ ; errs <- findLoadDLL ps []+ ; return $ fmap (intercalate ", ") errs+ }+ where+ fwk_file = rootname <.> "framework" </> rootname++ -- sorry for the hardcoded paths, I hope they won't change anytime soon:+ defaultFrameworkPaths = ["/Library/Frameworks", "/System/Library/Frameworks"]++ -- Try to call loadDLL for each candidate path.+ --+ -- See Note [macOS Big Sur dynamic libraries]+ findLoadDLL [] errs =+ -- Tried all our known library paths, but dlopen()+ -- has no built-in paths for frameworks: give up+ return $ Just errs+ findLoadDLL (p:ps) errs =+ do { dll <- loadDLL hsc_env (p </> fwk_file)+ ; case dll of+ Nothing -> return Nothing+ Just err -> findLoadDLL ps ((p ++ ": " ++ err):errs)+ }
+ compiler/GHC/Linker/Static.hs view
@@ -0,0 +1,341 @@+module GHC.Linker.Static+ ( linkBinary+ , linkBinary'+ , linkStaticLib+ , exeFileName+ )+where++import GHC.Prelude+import GHC.Platform+import GHC.Platform.Ways+import GHC.Settings++import GHC.SysTools+import GHC.SysTools.Ar+import GHC.SysTools.FileCleanup++import GHC.Unit.Types+import GHC.Unit.Info+import GHC.Unit.State++import GHC.Utils.Monad+import GHC.Utils.Misc+import GHC.Utils.Outputable++import GHC.Linker.MacOS+import GHC.Linker.Unit+import GHC.Linker.Dynamic+import GHC.Linker.ExtraObj+import GHC.Linker.Windows++import GHC.Driver.Session++import System.FilePath+import System.Directory+import Control.Monad++-----------------------------------------------------------------------------+-- Static linking, of .o files++-- The list of packages passed to link is the list of packages on+-- which this program depends, as discovered by the compilation+-- manager. It is combined with the list of packages that the user+-- specifies on the command line with -package flags.+--+-- In one-shot linking mode, we can't discover the package+-- dependencies (because we haven't actually done any compilation or+-- read any interface files), so the user must explicitly specify all+-- the packages.++{-+Note [-Xlinker -rpath vs -Wl,-rpath]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~++-Wl takes a comma-separated list of options which in the case of+-Wl,-rpath -Wl,some,path,with,commas parses the path with commas+as separate options.+Buck, the build system, produces paths with commas in them.++-Xlinker doesn't have this disadvantage and as far as I can tell+it is supported by both gcc and clang. Anecdotally nvcc supports+-Xlinker, but not -Wl.+-}++linkBinary :: DynFlags -> [FilePath] -> [UnitId] -> IO ()+linkBinary = linkBinary' False++linkBinary' :: Bool -> DynFlags -> [FilePath] -> [UnitId] -> IO ()+linkBinary' staticLink dflags o_files dep_units = do+ let platform = targetPlatform dflags+ toolSettings' = toolSettings dflags+ verbFlags = getVerbFlags dflags+ output_fn = exeFileName platform staticLink (outputFile dflags)+ home_unit = mkHomeUnitFromFlags dflags++ -- get the full list of packages to link with, by combining the+ -- explicit packages with the auto packages and all of their+ -- dependencies, and eliminating duplicates.++ full_output_fn <- if isAbsolute output_fn+ then return output_fn+ else do d <- getCurrentDirectory+ return $ normalise (d </> output_fn)+ pkg_lib_paths <- getUnitLibraryPath+ (initSDocContext dflags defaultUserStyle)+ (unitState dflags)+ home_unit+ (ways dflags)+ dep_units+ let pkg_lib_path_opts = concatMap get_pkg_lib_path_opts pkg_lib_paths+ get_pkg_lib_path_opts l+ | osElfTarget (platformOS platform) &&+ dynLibLoader dflags == SystemDependent &&+ WayDyn `elem` ways dflags+ = let libpath = if gopt Opt_RelativeDynlibPaths dflags+ then "$ORIGIN" </>+ (l `makeRelativeTo` full_output_fn)+ else l+ -- See Note [-Xlinker -rpath vs -Wl,-rpath]+ rpath = if gopt Opt_RPath dflags+ then ["-Xlinker", "-rpath", "-Xlinker", libpath]+ else []+ -- Solaris 11's linker does not support -rpath-link option. It silently+ -- ignores it and then complains about next option which is -l<some+ -- dir> as being a directory and not expected object file, E.g+ -- ld: elf error: file+ -- /tmp/ghc-src/libraries/base/dist-install/build:+ -- elf_begin: I/O error: region read: Is a directory+ rpathlink = if (platformOS platform) == OSSolaris2+ then []+ else ["-Xlinker", "-rpath-link", "-Xlinker", l]+ in ["-L" ++ l] ++ rpathlink ++ rpath+ | osMachOTarget (platformOS platform) &&+ dynLibLoader dflags == SystemDependent &&+ WayDyn `elem` ways dflags &&+ gopt Opt_RPath dflags+ = let libpath = if gopt Opt_RelativeDynlibPaths dflags+ then "@loader_path" </>+ (l `makeRelativeTo` full_output_fn)+ else l+ in ["-L" ++ l] ++ ["-Xlinker", "-rpath", "-Xlinker", libpath]+ | otherwise = ["-L" ++ l]++ pkg_lib_path_opts <-+ if gopt Opt_SingleLibFolder dflags+ then do+ libs <- getLibs dflags dep_units+ tmpDir <- newTempDir dflags+ sequence_ [ copyFile lib (tmpDir </> basename)+ | (lib, basename) <- libs]+ return [ "-L" ++ tmpDir ]+ else pure pkg_lib_path_opts++ let+ dead_strip+ | gopt Opt_WholeArchiveHsLibs dflags = []+ | otherwise = if osSubsectionsViaSymbols (platformOS platform)+ then ["-Wl,-dead_strip"]+ else []+ let lib_paths = libraryPaths dflags+ let lib_path_opts = map ("-L"++) lib_paths++ extraLinkObj <- mkExtraObjToLinkIntoBinary dflags+ noteLinkObjs <- mkNoteObjsToLinkIntoBinary dflags dep_units++ let+ (pre_hs_libs, post_hs_libs)+ | gopt Opt_WholeArchiveHsLibs dflags+ = if platformOS platform == OSDarwin+ then (["-Wl,-all_load"], [])+ -- OS X does not have a flag to turn off -all_load+ else (["-Wl,--whole-archive"], ["-Wl,--no-whole-archive"])+ | otherwise+ = ([],[])++ pkg_link_opts <- do+ (package_hs_libs, extra_libs, other_flags) <- getUnitLinkOpts dflags dep_units+ return $ if staticLink+ then package_hs_libs -- If building an executable really means making a static+ -- library (e.g. iOS), then we only keep the -l options for+ -- HS packages, because libtool doesn't accept other options.+ -- In the case of iOS these need to be added by hand to the+ -- final link in Xcode.+ else other_flags ++ dead_strip+ ++ pre_hs_libs ++ package_hs_libs ++ post_hs_libs+ ++ extra_libs+ -- -Wl,-u,<sym> contained in other_flags+ -- needs to be put before -l<package>,+ -- otherwise Solaris linker fails linking+ -- a binary with unresolved symbols in RTS+ -- which are defined in base package+ -- the reason for this is a note in ld(1) about+ -- '-u' option: "The placement of this option+ -- on the command line is significant.+ -- This option must be placed before the library+ -- that defines the symbol."++ -- frameworks+ pkg_framework_opts <- getUnitFrameworkOpts dflags platform dep_units+ let framework_opts = getFrameworkOpts dflags platform++ -- probably _stub.o files+ let extra_ld_inputs = ldInputs dflags++ rc_objs <- case platformOS platform of+ OSMinGW32 | gopt Opt_GenManifest dflags -> maybeCreateManifest dflags output_fn+ _ -> return []++ let link dflags args | staticLink = GHC.SysTools.runLibtool dflags args+ | platformOS platform == OSDarwin+ = do+ GHC.SysTools.runLink dflags args+ GHC.Linker.MacOS.runInjectRPaths dflags pkg_lib_paths output_fn+ | otherwise+ = GHC.SysTools.runLink dflags args++ link dflags (+ map GHC.SysTools.Option verbFlags+ ++ [ GHC.SysTools.Option "-o"+ , GHC.SysTools.FileOption "" output_fn+ ]+ ++ libmLinkOpts+ ++ map GHC.SysTools.Option (+ []++ -- See Note [No PIE when linking]+ ++ picCCOpts dflags++ -- Permit the linker to auto link _symbol to _imp_symbol.+ -- This lets us link against DLLs without needing an "import library".+ ++ (if platformOS platform == OSMinGW32+ then ["-Wl,--enable-auto-import"]+ else [])++ -- '-no_compact_unwind'+ -- C++/Objective-C exceptions cannot use optimised+ -- stack unwinding code. The optimised form is the+ -- default in Xcode 4 on at least x86_64, and+ -- without this flag we're also seeing warnings+ -- like+ -- ld: warning: could not create compact unwind for .LFB3: non-standard register 5 being saved in prolog+ -- on x86.+ ++ (if toolSettings_ldSupportsCompactUnwind toolSettings' &&+ not staticLink &&+ (platformOS platform == OSDarwin) &&+ case platformArch platform of+ ArchX86 -> True+ ArchX86_64 -> True+ ArchARM {} -> True+ ArchAArch64 -> True+ _ -> False+ then ["-Wl,-no_compact_unwind"]+ else [])++ -- '-Wl,-read_only_relocs,suppress'+ -- ld gives loads of warnings like:+ -- ld: warning: text reloc in _base_GHCziArr_unsafeArray_info to _base_GHCziArr_unsafeArray_closure+ -- when linking any program. We're not sure+ -- whether this is something we ought to fix, but+ -- for now this flags silences them.+ ++ (if platformOS platform == OSDarwin &&+ platformArch platform == ArchX86 &&+ not staticLink+ then ["-Wl,-read_only_relocs,suppress"]+ else [])++ ++ (if toolSettings_ldIsGnuLd toolSettings' &&+ not (gopt Opt_WholeArchiveHsLibs dflags)+ then ["-Wl,--gc-sections"]+ else [])++ ++ o_files+ ++ lib_path_opts)+ ++ extra_ld_inputs+ ++ map GHC.SysTools.Option (+ rc_objs+ ++ framework_opts+ ++ pkg_lib_path_opts+ ++ extraLinkObj:noteLinkObjs+ ++ pkg_link_opts+ ++ pkg_framework_opts+ ++ (if platformOS platform == OSDarwin+ -- dead_strip_dylibs, will remove unused dylibs, and thus save+ -- space in the load commands. The -headerpad is necessary so+ -- that we can inject more @rpath's later for the left over+ -- libraries during runInjectRpaths phase.+ --+ -- See Note [Dynamic linking on macOS].+ then [ "-Wl,-dead_strip_dylibs", "-Wl,-headerpad,8000" ]+ else [])+ ))++-- | Linking a static lib will not really link anything. It will merely produce+-- a static archive of all dependent static libraries. The resulting library+-- will still need to be linked with any remaining link flags.+linkStaticLib :: DynFlags -> [String] -> [UnitId] -> IO ()+linkStaticLib dflags o_files dep_units = do+ let platform = targetPlatform dflags+ extra_ld_inputs = [ f | FileOption _ f <- ldInputs dflags ]+ modules = o_files ++ extra_ld_inputs+ output_fn = exeFileName platform True (outputFile dflags)+ home_unit = mkHomeUnitFromFlags dflags++ full_output_fn <- if isAbsolute output_fn+ then return output_fn+ else do d <- getCurrentDirectory+ return $ normalise (d </> output_fn)+ output_exists <- doesFileExist full_output_fn+ (when output_exists) $ removeFile full_output_fn++ pkg_cfgs_init <- getPreloadUnitsAnd+ (initSDocContext dflags defaultUserStyle)+ (unitState dflags)+ home_unit+ dep_units++ let pkg_cfgs+ | gopt Opt_LinkRts dflags+ = pkg_cfgs_init+ | otherwise+ = filter ((/= rtsUnitId) . unitId) pkg_cfgs_init++ archives <- concatMapM (collectArchives dflags) pkg_cfgs++ ar <- foldl mappend+ <$> (Archive <$> mapM loadObj modules)+ <*> mapM loadAr archives++ if toolSettings_ldIsGnuLd (toolSettings dflags)+ then writeGNUAr output_fn $ afilter (not . isGNUSymdef) ar+ else writeBSDAr output_fn $ afilter (not . isBSDSymdef) ar++ -- run ranlib over the archive. write*Ar does *not* create the symbol index.+ runRanlib dflags [GHC.SysTools.FileOption "" output_fn]++++-- | Compute the output file name of a program.+--+-- StaticLink boolean is used to indicate if the program is actually a static library+-- (e.g., on iOS).+--+-- Use the provided filename (if any), otherwise use "main.exe" (Windows),+-- "a.out (otherwise without StaticLink set), "liba.a". In every case, add the+-- extension if it is missing.+exeFileName :: Platform -> Bool -> Maybe FilePath -> FilePath+exeFileName platform staticLink output_fn+ | Just s <- output_fn =+ case platformOS platform of+ OSMinGW32 -> s <?.> "exe"+ _ -> if staticLink+ then s <?.> "a"+ else s+ | otherwise =+ if platformOS platform == OSMinGW32+ then "main.exe"+ else if staticLink+ then "liba.a"+ else "a.out"+ where s <?.> ext | null (takeExtension s) = s <.> ext+ | otherwise = s
+ compiler/GHC/Linker/Unit.hs view
@@ -0,0 +1,134 @@++-- | Linking Haskell units+module GHC.Linker.Unit+ ( collectLinkOpts+ , collectArchives+ , collectLibraryPaths+ , getUnitLinkOpts+ , getUnitLibraryPath+ , getLibs+ , packageHsLibs+ )+where++import GHC.Prelude+import GHC.Platform.Ways+import GHC.Unit.Types+import GHC.Unit.Info+import GHC.Unit.State+import GHC.Unit.Home+import GHC.Utils.Outputable+import GHC.Utils.Panic+import GHC.Utils.Misc++import qualified GHC.Data.ShortText as ST++import GHC.Driver.Session++import qualified Data.Set as Set+import Data.List (isPrefixOf, stripPrefix)+import Control.Monad+import System.Directory+import System.FilePath++-- | Find all the link options in these and the preload packages,+-- returning (package hs lib options, extra library options, other flags)+getUnitLinkOpts :: DynFlags -> [UnitId] -> IO ([String], [String], [String])+getUnitLinkOpts dflags pkgs =+ collectLinkOpts dflags `fmap` getPreloadUnitsAnd+ (initSDocContext dflags defaultUserStyle)+ (unitState dflags)+ (mkHomeUnitFromFlags dflags)+ pkgs++collectLinkOpts :: DynFlags -> [UnitInfo] -> ([String], [String], [String])+collectLinkOpts dflags ps =+ (+ concatMap (map ("-l" ++) . packageHsLibs dflags) ps,+ concatMap (map ("-l" ++) . map ST.unpack . unitExtDepLibsSys) ps,+ concatMap (map ST.unpack . unitLinkerOptions) ps+ )++collectArchives :: DynFlags -> UnitInfo -> IO [FilePath]+collectArchives dflags pc =+ filterM doesFileExist [ searchPath </> ("lib" ++ lib ++ ".a")+ | searchPath <- searchPaths+ , lib <- libs ]+ where searchPaths = ordNub . filter notNull . libraryDirsForWay (ways dflags) $ pc+ libs = packageHsLibs dflags pc ++ map ST.unpack (unitExtDepLibsSys pc)++collectLibraryPaths :: Ways -> [UnitInfo] -> [FilePath]+collectLibraryPaths ws = ordNub . filter notNull+ . concatMap (libraryDirsForWay ws)++-- | Either the 'unitLibraryDirs' or 'unitLibraryDynDirs' as appropriate for the way.+libraryDirsForWay :: Ways -> UnitInfo -> [String]+libraryDirsForWay ws+ | WayDyn `elem` ws = map ST.unpack . unitLibraryDynDirs+ | otherwise = map ST.unpack . unitLibraryDirs++getLibs :: DynFlags -> [UnitId] -> IO [(String,String)]+getLibs dflags pkgs = do+ ps <- getPreloadUnitsAnd+ (initSDocContext dflags defaultUserStyle)+ (unitState dflags)+ (mkHomeUnitFromFlags dflags)+ pkgs+ fmap concat . forM ps $ \p -> do+ let candidates = [ (l </> f, f) | l <- collectLibraryPaths (ways dflags) [p]+ , f <- (\n -> "lib" ++ n ++ ".a") <$> packageHsLibs dflags p ]+ filterM (doesFileExist . fst) candidates++-- | Find all the library paths in these and the preload packages+getUnitLibraryPath :: SDocContext -> UnitState -> HomeUnit -> Ways -> [UnitId] -> IO [String]+getUnitLibraryPath ctx unit_state home_unit ws pkgs =+ collectLibraryPaths ws `fmap` getPreloadUnitsAnd ctx unit_state home_unit pkgs++packageHsLibs :: DynFlags -> UnitInfo -> [String]+packageHsLibs dflags p = map (mkDynName . addSuffix . ST.unpack) (unitLibraries p)+ where+ ways0 = ways dflags++ ways1 = Set.filter (/= WayDyn) ways0+ -- the name of a shared library is libHSfoo-ghc<version>.so+ -- we leave out the _dyn, because it is superfluous++ -- debug and profiled RTSs include support for -eventlog+ ways2 | WayDebug `Set.member` ways1 || WayProf `Set.member` ways1+ = Set.filter (/= WayTracing) ways1+ | otherwise+ = ways1++ tag = waysTag (fullWays ways2)+ rts_tag = waysTag ways2++ mkDynName x+ | not (ways dflags `hasWay` WayDyn) = x+ | "HS" `isPrefixOf` x =+ x ++ '-':programName dflags ++ projectVersion dflags+ -- For non-Haskell libraries, we use the name "Cfoo". The .a+ -- file is libCfoo.a, and the .so is libfoo.so. That way the+ -- linker knows what we mean for the vanilla (-lCfoo) and dyn+ -- (-lfoo) ways. We therefore need to strip the 'C' off here.+ | Just x' <- stripPrefix "C" x = x'+ | otherwise+ = panic ("Don't understand library name " ++ x)++ -- Add _thr and other rts suffixes to packages named+ -- `rts` or `rts-1.0`. Why both? Traditionally the rts+ -- package is called `rts` only. However the tooling+ -- usually expects a package name to have a version.+ -- As such we will gradually move towards the `rts-1.0`+ -- package name, at which point the `rts` package name+ -- will eventually be unused.+ --+ -- This change elevates the need to add custom hooks+ -- and handling specifically for the `rts` package for+ -- example in ghc-cabal.+ addSuffix rts@"HSrts" = rts ++ (expandTag rts_tag)+ addSuffix rts@"HSrts-1.0"= rts ++ (expandTag rts_tag)+ addSuffix other_lib = other_lib ++ (expandTag tag)++ expandTag t | null t = ""+ | otherwise = '_':t+
+ compiler/GHC/Linker/Windows.hs view
@@ -0,0 +1,64 @@+module GHC.Linker.Windows+ ( maybeCreateManifest+ )+where++import GHC.Prelude+import GHC.SysTools+import GHC.Driver.Session+import GHC.SysTools.FileCleanup++import System.FilePath+import System.Directory++maybeCreateManifest+ :: DynFlags+ -> FilePath -- ^ filename of executable+ -> IO [FilePath] -- ^ extra objects to embed, maybe+maybeCreateManifest dflags exe_filename = do+ let manifest_filename = exe_filename <.> "manifest"+ manifest =+ "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n\+ \ <assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">\n\+ \ <assemblyIdentity version=\"1.0.0.0\"\n\+ \ processorArchitecture=\"X86\"\n\+ \ name=\"" ++ dropExtension exe_filename ++ "\"\n\+ \ type=\"win32\"/>\n\n\+ \ <trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v3\">\n\+ \ <security>\n\+ \ <requestedPrivileges>\n\+ \ <requestedExecutionLevel level=\"asInvoker\" uiAccess=\"false\"/>\n\+ \ </requestedPrivileges>\n\+ \ </security>\n\+ \ </trustInfo>\n\+ \</assembly>\n"++ writeFile manifest_filename manifest++ -- Windows will find the manifest file if it is named+ -- foo.exe.manifest. However, for extra robustness, and so that+ -- we can move the binary around, we can embed the manifest in+ -- the binary itself using windres:+ if not (gopt Opt_EmbedManifest dflags)+ then return []+ else do+ rc_filename <- newTempName dflags TFL_CurrentModule "rc"+ rc_obj_filename <-+ newTempName dflags TFL_GhcSession (objectSuf dflags)++ writeFile rc_filename $+ "1 24 MOVEABLE PURE " ++ show manifest_filename ++ "\n"+ -- magic numbers :-)+ -- show is a bit hackish above, but we need to escape the+ -- backslashes in the path.++ runWindres dflags $ map GHC.SysTools.Option $+ ["--input="++rc_filename,+ "--output="++rc_obj_filename,+ "--output-format=coff"]+ -- no FileOptions here: windres doesn't like seeing+ -- backslashes, apparently++ removeFile manifest_filename++ return [rc_obj_filename]
compiler/GHC/Rename/HsType.hs view
@@ -12,7 +12,7 @@ rnHsType, rnLHsType, rnLHsTypes, rnContext, rnHsKind, rnLHsKind, rnLHsTypeArgs, rnHsSigType, rnHsWcType,- HsSigWcTypeScoping(..), rnHsSigWcType, rnHsPatSigType,+ HsPatSigTypeScoping(..), rnHsSigWcType, rnHsPatSigType, newTyVarNameRn, rnConDeclFields, rnLTyVar,@@ -24,15 +24,15 @@ checkPrecMatch, checkSectionPrec, -- Binding related stuff- bindHsForAllTelescope,+ bindHsOuterTyVarBndrs, bindHsForAllTelescope, bindLHsTyVarBndr, bindLHsTyVarBndrs, WarnUnusedForalls(..), rnImplicitBndrs, bindSigTyVarsFV, bindHsQTyVars, FreeKiTyVars, extractHsTyRdrTyVars, extractHsTyRdrTyVarsKindVars, extractHsTysRdrTyVars, extractRdrKindSigVars, extractConDeclGADTDetailsTyVars, extractDataDefnKindVars,- extractHsTvBndrs, extractHsTyArgRdrKiTyVars,- forAllOrNothing, nubL+ extractHsOuterTvBndrs, extractHsTyArgRdrKiTyVars,+ nubL ) where import GHC.Prelude@@ -82,7 +82,7 @@ ********************************************************* -} -data HsSigWcTypeScoping+data HsPatSigTypeScoping = AlwaysBind -- ^ Always bind any free tyvars of the given type, regardless of whether we -- have a forall at the top.@@ -103,10 +103,6 @@ -- variables. If a RULE explicitly quantifies its type variables, then -- 'NeverBind' is used instead. See also -- @Note [Pattern signature binders and scoping]@ in "GHC.Hs.Type".- | BindUnlessForall- -- ^ Unless there's forall at the top, do the same thing as 'AlwaysBind'.- -- This is only ever used in places where the \"@forall@-or-nothing\" rule- -- is in effect. See @Note [forall-or-nothing rule]@. | NeverBind -- ^ Never bind any free tyvars. This is used for RULES that have both -- explicit type and term variable binders, e.g.:@@ -124,13 +120,19 @@ rnHsSigWcType :: HsDocContext -> LHsSigWcType GhcPs -> RnM (LHsSigWcType GhcRn, FreeVars)-rnHsSigWcType doc (HsWC { hswc_body = HsIB { hsib_body = hs_ty }})- = rn_hs_sig_wc_type BindUnlessForall doc hs_ty $ \nwcs imp_tvs body ->- let ib_ty = HsIB { hsib_ext = imp_tvs, hsib_body = body }- wc_ty = HsWC { hswc_ext = nwcs, hswc_body = ib_ty } in- pure (wc_ty, emptyFVs)+rnHsSigWcType doc (HsWC { hswc_body =+ sig_ty@(L loc (HsSig{sig_bndrs = outer_bndrs, sig_body = body_ty })) })+ = do { free_vars <- filterInScopeM (extract_lhs_sig_ty sig_ty)+ ; (nwc_rdrs', imp_tv_nms) <- partition_nwcs free_vars+ ; let nwc_rdrs = nubL nwc_rdrs'+ ; bindHsOuterTyVarBndrs doc Nothing imp_tv_nms outer_bndrs $ \outer_bndrs' ->+ do { (wcs, body_ty', fvs) <- rnWcBody doc nwc_rdrs body_ty+ ; pure ( HsWC { hswc_ext = wcs, hswc_body = L loc $+ HsSig { sig_ext = noExtField+ , sig_bndrs = outer_bndrs', sig_body = body_ty' }}+ , fvs) } } -rnHsPatSigType :: HsSigWcTypeScoping+rnHsPatSigType :: HsPatSigTypeScoping -> HsDocContext -> HsPatSigType GhcPs -> (HsPatSigType GhcRn -> RnM (a, FreeVars))@@ -145,33 +147,20 @@ rnHsPatSigType scoping ctx sig_ty thing_inside = do { ty_sig_okay <- xoptM LangExt.ScopedTypeVariables ; checkErr ty_sig_okay (unexpectedPatSigTypeErr sig_ty)- ; rn_hs_sig_wc_type scoping ctx (hsPatSigType sig_ty) $- \nwcs imp_tvs body ->- do { let sig_names = HsPSRn { hsps_nwcs = nwcs, hsps_imp_tvs = imp_tvs }- sig_ty' = HsPS { hsps_ext = sig_names, hsps_body = body }- ; thing_inside sig_ty'- } }---- The workhorse for rnHsSigWcType and rnHsPatSigType.-rn_hs_sig_wc_type :: HsSigWcTypeScoping -> HsDocContext- -> LHsType GhcPs- -> ([Name] -- Wildcard names- -> [Name] -- Implicitly bound type variable names- -> LHsType GhcRn- -> RnM (a, FreeVars))- -> RnM (a, FreeVars)-rn_hs_sig_wc_type scoping ctxt hs_ty thing_inside- = do { free_vars <- filterInScopeM (extractHsTyRdrTyVars hs_ty)+ ; free_vars <- filterInScopeM (extractHsTyRdrTyVars pat_sig_ty) ; (nwc_rdrs', tv_rdrs) <- partition_nwcs free_vars ; let nwc_rdrs = nubL nwc_rdrs'- ; implicit_bndrs <- case scoping of- AlwaysBind -> pure tv_rdrs- BindUnlessForall -> forAllOrNothing (isLHsInvisForAllTy hs_ty) tv_rdrs- NeverBind -> pure []- ; rnImplicitBndrs Nothing implicit_bndrs $ \ vars ->- do { (wcs, hs_ty', fvs1) <- rnWcBody ctxt nwc_rdrs hs_ty- ; (res, fvs2) <- thing_inside wcs vars hs_ty'+ implicit_bndrs = case scoping of+ AlwaysBind -> tv_rdrs+ NeverBind -> []+ ; rnImplicitBndrs Nothing implicit_bndrs $ \ imp_tvs ->+ do { (nwcs, pat_sig_ty', fvs1) <- rnWcBody ctx nwc_rdrs pat_sig_ty+ ; let sig_names = HsPSRn { hsps_nwcs = nwcs, hsps_imp_tvs = imp_tvs }+ sig_ty' = HsPS { hsps_ext = sig_names, hsps_body = pat_sig_ty' }+ ; (res, fvs2) <- thing_inside sig_ty' ; return (res, fvs1 `plusFV` fvs2) } }+ where+ pat_sig_ty = hsPatSigType sig_ty rnHsWcType :: HsDocContext -> LHsWcType GhcPs -> RnM (LHsWcType GhcRn, FreeVars) rnHsWcType ctxt (HsWC { hswc_body = hs_ty })@@ -306,7 +295,7 @@ ********************************************************* * *- HsSigtype (i.e. no wildcards)+ HsSigType (i.e. no wildcards) * * ****************************************************** -} @@ -316,76 +305,22 @@ -> RnM (LHsSigType GhcRn, FreeVars) -- Used for source-language type signatures -- that cannot have wildcards-rnHsSigType ctx level (HsIB { hsib_body = hs_ty })- = do { traceRn "rnHsSigType" (ppr hs_ty)- ; rdr_env <- getLocalRdrEnv- ; vars0 <- forAllOrNothing (isLHsInvisForAllTy hs_ty)- $ filterInScope rdr_env- $ extractHsTyRdrTyVars hs_ty- ; rnImplicitBndrs Nothing vars0 $ \ vars ->- do { (body', fvs) <- rnLHsTyKi (mkTyKiEnv ctx level RnTypeBody) hs_ty+rnHsSigType ctx level+ (L loc sig_ty@(HsSig { sig_bndrs = outer_bndrs, sig_body = body }))+ = setSrcSpan loc $+ do { traceRn "rnHsSigType" (ppr sig_ty)+ ; case outer_bndrs of+ HsOuterExplicit{} -> checkPolyKinds env sig_ty+ HsOuterImplicit{} -> pure ()+ ; imp_vars <- filterInScopeM $ extractHsTyRdrTyVars body+ ; bindHsOuterTyVarBndrs ctx Nothing imp_vars outer_bndrs $ \outer_bndrs' ->+ do { (body', fvs) <- rnLHsTyKi env body - ; return ( HsIB { hsib_ext = vars- , hsib_body = body' }+ ; return ( L loc $ HsSig { sig_ext = noExtField+ , sig_bndrs = outer_bndrs', sig_body = body' } , fvs ) } }--{--Note [forall-or-nothing rule]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-Free variables in signatures are usually bound in an implicit 'forall' at the-beginning of user-written signatures. However, if the signature has an-explicit, invisible forall at the beginning, this is disabled.--The idea is nested foralls express something which is only expressible-explicitly, while a top level forall could (usually) be replaced with an-implicit binding. Top-level foralls alone ("forall.") are therefore an-indication that the user is trying to be fastidious, so we don't implicitly-bind any variables.--Note that this rule only applies to outermost /in/visible 'forall's, and not-outermost visible 'forall's. See #18660 for more on this point.--Here are some concrete examples to demonstrate the forall-or-nothing rule in-action:-- type F1 :: a -> b -> b -- Legal; a,b are implicitly quantified.- -- Equivalently: forall a b. a -> b -> b-- type F2 :: forall a b. a -> b -> b -- Legal; explicitly quantified-- type F3 :: forall a. a -> b -> b -- Illegal; the forall-or-nothing rule says that- -- if you quantify a, you must also quantify b-- type F4 :: forall a -> b -> b -- Legal; the top quantifier (forall a) is a /visible/- -- quantifer, so the "nothing" part of the forall-or-nothing- -- rule applies, and b is therefore implicitly quantified.- -- Equivalently: forall b. forall a -> b -> b-- type F5 :: forall b. forall a -> b -> c -- Illegal; the forall-or-nothing rule says that- -- if you quantify b, you must also quantify c-- type F6 :: forall a -> forall b. b -> c -- Legal: just like F4.--}---- | See @Note [forall-or-nothing rule]@. This tiny little function is used--- (rather than its small body inlined) to indicate that we are implementing--- that rule.-forAllOrNothing :: Bool- -- ^ True <=> explicit forall- -- E.g. f :: forall a. a->b- -- we do not want to bring 'b' into scope, hence True- -- But f :: a -> b- -- we want to bring both 'a' and 'b' into scope, hence False- -> FreeKiTyVars- -- ^ Free vars of the type- -> RnM FreeKiTyVars-forAllOrNothing has_outer_forall fvs = case has_outer_forall of- True -> do- traceRn "forAllOrNothing" $ text "has explicit outer forall"- pure []- False -> do- traceRn "forAllOrNothing" $ text "no explicit forall. implicit binders:" <+> ppr fvs- pure fvs+ where+ env = mkTyKiEnv ctx level RnTypeBody rnImplicitBndrs :: Maybe assoc -- ^ @'Just' _@ => an associated type decl@@ -1053,6 +988,28 @@ -Wunused-foralls warnings in exactly one place: in bindHsQTyVars. -} +bindHsOuterTyVarBndrs :: OutputableBndrFlag flag+ => HsDocContext+ -> Maybe assoc+ -- ^ @'Just' _@ => an associated type decl+ -> FreeKiTyVars+ -> HsOuterTyVarBndrs flag GhcPs+ -> (HsOuterTyVarBndrs flag GhcRn -> RnM (a, FreeVars))+ -> RnM (a, FreeVars)+bindHsOuterTyVarBndrs doc mb_cls implicit_vars outer_bndrs thing_inside =+ case outer_bndrs of+ HsOuterImplicit{} ->+ rnImplicitBndrs mb_cls implicit_vars $ \implicit_vars' ->+ thing_inside $ HsOuterImplicit { hso_ximplicit = implicit_vars' }+ HsOuterExplicit{hso_bndrs = exp_bndrs} ->+ -- Note: If we pass mb_cls instead of Nothing below, bindLHsTyVarBndrs+ -- will use class variables for any names the user meant to bring in+ -- scope here. This is an explicit forall, so we want fresh names, not+ -- class variables. Thus: always pass Nothing.+ bindLHsTyVarBndrs doc WarnUnusedForalls Nothing exp_bndrs $ \exp_bndrs' ->+ thing_inside $ HsOuterExplicit { hso_xexplicit = noExtField+ , hso_bndrs = exp_bndrs' }+ bindHsForAllTelescope :: HsDocContext -> HsForAllTelescope GhcPs -> (HsForAllTelescope GhcRn -> RnM (a, FreeVars))@@ -1859,6 +1816,10 @@ -- We deal with these separately in rnLHsTypeWithWildCards HsWildCardTy {} -> acc +extract_lhs_sig_ty :: LHsSigType GhcPs -> FreeKiTyVars+extract_lhs_sig_ty (L _ (HsSig{sig_bndrs = outer_bndrs, sig_body = body})) =+ extractHsOuterTvBndrs outer_bndrs $ extract_lty body []+ extract_hs_arrow :: HsArrow GhcPs -> FreeKiTyVars -> FreeKiTyVars extract_hs_arrow (HsExplicitMult _ p) acc = extract_lty p acc@@ -1875,11 +1836,13 @@ HsForAllInvis { hsf_invis_bndrs = bndrs } -> extract_hs_tv_bndrs bndrs acc_vars body_fvs -extractHsTvBndrs :: [LHsTyVarBndr flag GhcPs]- -> FreeKiTyVars -- Free in body- -> FreeKiTyVars -- Free in result-extractHsTvBndrs tv_bndrs body_fvs- = extract_hs_tv_bndrs tv_bndrs [] body_fvs+extractHsOuterTvBndrs :: HsOuterTyVarBndrs flag GhcPs+ -> FreeKiTyVars -- Free in body+ -> FreeKiTyVars -- Free in result+extractHsOuterTvBndrs outer_bndrs body_fvs =+ case outer_bndrs of+ HsOuterImplicit{} -> body_fvs+ HsOuterExplicit{hso_bndrs = bndrs} -> extract_hs_tv_bndrs bndrs [] body_fvs extract_hs_tv_bndrs :: [LHsTyVarBndr flag GhcPs] -> FreeKiTyVars -- Accumulator
compiler/GHC/Rename/Module.hs view
@@ -73,7 +73,7 @@ import Data.List ( mapAccumL ) import qualified Data.List.NonEmpty as NE import Data.List.NonEmpty ( NonEmpty(..) )-import Data.Maybe ( isNothing, isJust, fromMaybe, mapMaybe )+import Data.Maybe ( isNothing, fromMaybe, mapMaybe ) import qualified Data.Set as Set ( difference, fromList, toList, null ) import Data.Function ( on ) @@ -658,25 +658,25 @@ addErrAt l $ withHsDocContext ctxt err_msg pure $ mkUnboundName (mkTcOccFS (fsLit "<class>")) -rnFamInstEqn :: HsDocContext- -> AssocTyFamInfo- -> FreeKiTyVars- -- ^ Kind variables from the equation's RHS to be implicitly bound- -- if no explicit forall.- -> FamInstEqn GhcPs rhs- -> (HsDocContext -> rhs -> RnM (rhs', FreeVars))- -> RnM (FamInstEqn GhcRn rhs', FreeVars)-rnFamInstEqn doc atfi rhs_kvars- (HsIB { hsib_body = FamEqn { feqn_tycon = tycon- , feqn_bndrs = mb_bndrs- , feqn_pats = pats- , feqn_fixity = fixity- , feqn_rhs = payload }}) rn_payload+rnFamEqn :: HsDocContext+ -> AssocTyFamInfo+ -> FreeKiTyVars+ -- ^ Kind variables from the equation's RHS to be implicitly bound+ -- if no explicit forall.+ -> FamEqn GhcPs rhs+ -> (HsDocContext -> rhs -> RnM (rhs', FreeVars))+ -> RnM (FamEqn GhcRn rhs', FreeVars)+rnFamEqn doc atfi rhs_kvars+ (FamEqn { feqn_tycon = tycon+ , feqn_bndrs = outer_bndrs+ , feqn_pats = pats+ , feqn_fixity = fixity+ , feqn_rhs = payload }) rn_payload = do { tycon' <- lookupFamInstName mb_cls tycon -- all_imp_vars represent the implicitly bound type variables. This is -- empty if we have an explicit `forall` (see- -- Note [forall-or-nothing rule] in GHC.Rename.HsType), which means+ -- Note [forall-or-nothing rule] in GHC.Hs.Type), which means -- ignoring: -- -- - pat_kity_vars_with_dups, the variables mentioned in the LHS of@@ -696,31 +696,22 @@ -- type instance F [(a, b)] c = a -> b -> c -- -- all_imp_vars = [a, b, c] -- @- ; all_imp_vars <- forAllOrNothing (isJust mb_bndrs) $- -- No need to filter out explicit binders (the 'mb_bndrs = Just- -- explicit_bndrs' case) because there must be none if we're going- -- to implicitly bind anything, per the previous comment.- pat_kity_vars_with_dups ++ rhs_kvars+ ; let all_imp_vars = pat_kity_vars_with_dups ++ rhs_kvars - ; rnImplicitBndrs mb_cls all_imp_vars $ \all_imp_var_names' ->- bindLHsTyVarBndrs doc WarnUnusedForalls- Nothing (fromMaybe [] mb_bndrs) $ \bndrs' ->- -- Note: If we pass mb_cls instead of Nothing here,- -- bindLHsTyVarBndrs will use class variables for any names- -- the user meant to bring in scope here. This is an explicit- -- forall, so we want fresh names, not class variables.- -- Thus: always pass Nothing+ ; bindHsOuterTyVarBndrs doc mb_cls all_imp_vars outer_bndrs $ \rn_outer_bndrs -> do { (pats', pat_fvs) <- rnLHsTypeArgs (FamPatCtx tycon) pats ; (payload', rhs_fvs) <- rn_payload doc payload -- Report unused binders on the LHS -- See Note [Unused type variables in family instances]- ; let -- The SrcSpan that rnImplicitBndrs will attach to each Name will+ ; let -- The SrcSpan that bindHsOuterFamEqnTyVarBndrs will attach to each+ -- implicitly bound type variable Name in outer_bndrs' will -- span the entire type family instance, which will be reflected in -- -Wunused-type-patterns warnings. We can be a little more precise -- than that by pointing to the LHS of the instance instead, which -- is what lhs_loc corresponds to.- all_imp_var_names = map (`setNameLoc` lhs_loc) all_imp_var_names'+ rn_outer_bndrs' = mapHsOuterImplicit (map (`setNameLoc` lhs_loc))+ rn_outer_bndrs groups :: [NonEmpty (Located RdrName)] groups = equivClasses cmpLocated $@@ -735,7 +726,7 @@ -- Note [Unused type variables in family instances] ; let nms_used = extendNameSetList rhs_fvs $ inst_tvs ++ nms_dups- all_nms = all_imp_var_names ++ hsLTyVarNames bndrs'+ all_nms = hsOuterTyVarNames rn_outer_bndrs' ; warnUnusedTypePatterns all_nms nms_used ; let eqn_fvs = rhs_fvs `plusFV` pat_fvs@@ -745,14 +736,13 @@ -> eqn_fvs _ -> eqn_fvs `addOneFV` unLoc tycon' - ; return (HsIB { hsib_ext = all_imp_var_names -- Note [Wildcards in family instances]- , hsib_body- = FamEqn { feqn_ext = noExtField- , feqn_tycon = tycon'- , feqn_bndrs = bndrs' <$ mb_bndrs- , feqn_pats = pats'- , feqn_fixity = fixity- , feqn_rhs = payload' } },+ ; return (FamEqn { feqn_ext = noExtField+ , feqn_tycon = tycon'+ -- Note [Wildcards in family instances]+ , feqn_bndrs = rn_outer_bndrs'+ , feqn_pats = pats'+ , feqn_fixity = fixity+ , feqn_rhs = payload' }, all_fvs) } } where -- The parent class, if we are dealing with an associated type family@@ -780,7 +770,7 @@ -- type instance F a b c = Either a b -- ^^^^^ lhs_loc = case map lhsTypeArgSrcSpan pats ++ map getLoc rhs_kvars of- [] -> panic "rnFamInstEqn.lhs_loc"+ [] -> panic "rnFamEqn.lhs_loc" [loc] -> loc (loc:locs) -> loc `combineSrcSpans` last locs @@ -838,10 +828,8 @@ rnTyFamInstEqn :: AssocTyFamInfo -> TyFamInstEqn GhcPs -> RnM (TyFamInstEqn GhcRn, FreeVars)-rnTyFamInstEqn atfi- eqn@(HsIB { hsib_body = FamEqn { feqn_tycon = tycon- , feqn_rhs = rhs }})- = rnFamInstEqn (TySynCtx tycon) atfi rhs_kvs eqn rnTySyn+rnTyFamInstEqn atfi eqn@(FamEqn { feqn_tycon = tycon, feqn_rhs = rhs })+ = rnFamEqn (TySynCtx tycon) atfi rhs_kvs eqn rnTySyn where rhs_kvs = extractHsTyRdrTyVarsKindVars rhs @@ -853,12 +841,12 @@ rnDataFamInstDecl :: AssocTyFamInfo -> DataFamInstDecl GhcPs -> RnM (DataFamInstDecl GhcRn, FreeVars)-rnDataFamInstDecl atfi (DataFamInstDecl { dfid_eqn = eqn@(HsIB { hsib_body =- FamEqn { feqn_tycon = tycon- , feqn_rhs = rhs }})})+rnDataFamInstDecl atfi (DataFamInstDecl { dfid_eqn =+ eqn@(FamEqn { feqn_tycon = tycon+ , feqn_rhs = rhs })}) = do { let rhs_kvs = extractDataDefnKindVars rhs ; (eqn', fvs) <-- rnFamInstEqn (TyDataCtx tycon) atfi rhs_kvs eqn rnDataDefn+ rnFamEqn (TyDataCtx tycon) atfi rhs_kvs eqn rnDataDefn ; return (DataFamInstDecl { dfid_eqn = eqn' }, fvs) } -- Renaming of the associated types in instances.@@ -1065,7 +1053,7 @@ where ctxt = DerivDeclCtx inf_err = Just (text "Inferred type variables are not allowed")- loc = getLoc $ hsib_body nowc_ty+ loc = getLoc nowc_ty nowc_ty = dropWildCards ty standaloneDerivErr :: SDoc@@ -1931,17 +1919,15 @@ ViaStrategy via_ty -> do checkInferredVars doc inf_err via_ty (via_ty', fvs1) <- rnHsSigType doc TypeLevel via_ty- let HsIB { hsib_ext = via_imp_tvs- , hsib_body = via_body } = via_ty'- (via_exp_tv_bndrs, via_rho) = splitLHsForAllTyInvis_KP via_body- via_exp_tvs = maybe [] hsLTyVarNames via_exp_tv_bndrs- via_tvs = via_imp_tvs ++ via_exp_tvs+ let HsSig { sig_bndrs = via_outer_bndrs+ , sig_body = via_body } = unLoc via_ty'+ via_tvs = hsOuterTyVarNames via_outer_bndrs -- Check if there are any nested `forall`s, which are illegal in a -- `via` type. -- See Note [No nested foralls or contexts in instance types] -- (Wrinkle: Derived instances) in GHC.Hs.Type. addNoNestedForallsContextsErr doc- (quotes (text "via") <+> text "type") via_rho+ (quotes (text "via") <+> text "type") via_body (thing, fvs2) <- extendTyVarEnvFVRn via_tvs thing_inside pure (ViaStrategy via_ty', thing, fvs1 `plusFV` fvs2) @@ -2194,32 +2180,29 @@ , con_forall = forall }, -- Remove when #18311 is fixed all_fvs) }} -rnConDecl decl@(ConDeclGADT { con_names = names- , con_forall = forall@(L _ explicit_forall)- , con_qvars = explicit_tkvs- , con_mb_cxt = mcxt- , con_g_args = args- , con_res_ty = res_ty- , con_doc = mb_doc })+rnConDecl (ConDeclGADT { con_names = names+ , con_bndrs = L l outer_bndrs+ , con_mb_cxt = mcxt+ , con_g_args = args+ , con_res_ty = res_ty+ , con_doc = mb_doc }) = do { mapM_ (addLocM checkConName) names ; new_names <- mapM lookupLocatedTopBndrRn names - -- We must ensure that we extract the free tkvs in left-to-right- -- order of their appearance in the constructor type.- -- That order governs the order the implicitly-quantified type- -- variable, and hence the order needed for visible type application- -- See #14808.- ; implicit_bndrs <- forAllOrNothing explicit_forall- $ extractHsTvBndrs explicit_tkvs- $ extractHsTysRdrTyVars (hsConDeclTheta mcxt)- $ extractConDeclGADTDetailsTyVars args- $ extractHsTyRdrTyVars res_ty+ ; let -- We must ensure that we extract the free tkvs in left-to-right+ -- order of their appearance in the constructor type.+ -- That order governs the order the implicitly-quantified type+ -- variable, and hence the order needed for visible type application+ -- See #14808.+ implicit_bndrs =+ extractHsOuterTvBndrs outer_bndrs $+ extractHsTysRdrTyVars (hsConDeclTheta mcxt) $+ extractConDeclGADTDetailsTyVars args $+ extractHsTysRdrTyVars [res_ty] [] ; let ctxt = ConDeclCtx new_names - ; rnImplicitBndrs Nothing implicit_bndrs $ \ implicit_tkvs ->- bindLHsTyVarBndrs ctxt WarnUnusedForalls- Nothing explicit_tkvs $ \ explicit_tkvs ->+ ; bindHsOuterTyVarBndrs ctxt Nothing implicit_bndrs outer_bndrs $ \outer_bndrs' -> do { (new_cxt, fvs1) <- rnMbContext ctxt mcxt ; (new_args, fvs2) <- rnConDeclGADTDetails (unLoc (head new_names)) ctxt args ; (new_res_ty, fvs3) <- rnLHsType ctxt res_ty@@ -2233,12 +2216,11 @@ ; let all_fvs = fvs1 `plusFV` fvs2 `plusFV` fvs3 ; traceRn "rnConDecl (ConDeclGADT)"- (ppr names $$ ppr implicit_tkvs $$ ppr explicit_tkvs)- ; return (decl { con_g_ext = implicit_tkvs, con_names = new_names- , con_qvars = explicit_tkvs, con_mb_cxt = new_cxt- , con_g_args = new_args, con_res_ty = new_res_ty- , con_doc = mb_doc- , con_forall = forall }, -- Remove when #18311 is fixed+ (ppr names $$ ppr outer_bndrs')+ ; return (ConDeclGADT { con_g_ext = noExtField, con_names = new_names+ , con_bndrs = L l outer_bndrs', con_mb_cxt = new_cxt+ , con_g_args = new_args, con_res_ty = new_res_ty+ , con_doc = mb_doc }, all_fvs) } } rnMbContext :: HsDocContext -> Maybe (LHsContext GhcPs)
compiler/GHC/Rename/Names.hs view
@@ -830,8 +830,7 @@ new_di :: Bool -> Maybe Name -> DataFamInstDecl GhcPs -> RnM (AvailInfo, [(Name, [FieldLabel])])- new_di overload_ok mb_cls dfid@(DataFamInstDecl { dfid_eqn =- HsIB { hsib_body = ti_decl }})+ new_di overload_ok mb_cls dfid@(DataFamInstDecl { dfid_eqn = ti_decl }) = do { main_name <- lookupFamInstName mb_cls (feqn_tycon ti_decl) ; let (bndrs, flds) = hsDataFamInstBinders dfid ; sub_names <- mapM newTopSrcBinder bndrs
compiler/GHC/Rename/Utils.hs view
@@ -194,17 +194,14 @@ -> RnM () checkInferredVars _ Nothing _ = return () checkInferredVars ctxt (Just msg) ty =- let bndrs = forallty_bndrs (hsSigType ty)+ let bndrs = sig_ty_bndrs ty in case find ((==) InferredSpec . hsTyVarBndrFlag) bndrs of Nothing -> return () Just _ -> addErr $ withHsDocContext ctxt msg where- forallty_bndrs :: LHsType GhcPs -> [HsTyVarBndr Specificity GhcPs]- forallty_bndrs (L _ ty) = case ty of- HsParTy _ ty' -> forallty_bndrs ty'- HsForAllTy { hst_tele = HsForAllInvis { hsf_invis_bndrs = tvs }}- -> map unLoc tvs- _ -> []+ sig_ty_bndrs :: LHsSigType GhcPs -> [HsTyVarBndr Specificity GhcPs]+ sig_ty_bndrs (L _ (HsSig{sig_bndrs = outer_bndrs}))+ = map unLoc (hsOuterExplicitBndrs outer_bndrs) {- Note [Unobservably inferred type variables]
compiler/GHC/Runtime/Debugger.hs view
@@ -21,7 +21,8 @@ import GHC.Driver.Monad import GHC.Driver.Env -import GHC.Runtime.Linker+import GHC.Linker.Loader+ import GHC.Runtime.Heap.Inspect import GHC.Runtime.Interpreter import GHC.Runtime.Context@@ -131,8 +132,8 @@ let ids = [ mkVanillaGlobal name ty | (name,ty) <- zip names tys] new_ic = extendInteractiveContextWithIds ictxt ids- dl = hsc_dynLinker hsc_env- liftIO $ extendLinkEnv dl (zip names fhvs)+ dl = hsc_loader hsc_env+ liftIO $ extendLoadedEnv dl (zip names fhvs) setSession hsc_env {hsc_IC = new_ic } return t' where@@ -186,9 +187,9 @@ expr = "Prelude.return (Prelude.show " ++ showPpr dflags bname ++ ") :: Prelude.IO Prelude.String"- dl = hsc_dynLinker hsc_env+ dl = hsc_loader hsc_env GHC.setSessionDynFlags dflags{log_action=noop_log}- txt_ <- withExtendedLinkEnv dl+ txt_ <- withExtendedLoadedEnv dl [(bname, fhv)] (GHC.compileExprRemote expr) let myprec = 10 -- application precedence. TODO Infix constructors
compiler/GHC/Runtime/Eval.hs view
@@ -59,14 +59,15 @@ import GHC.Runtime.Eval.Types import GHC.Runtime.Interpreter as GHCi import GHC.Runtime.Interpreter.Types-import GHC.Runtime.Linker as Linker-import GHC.Runtime.Linker.Types import GHC.Runtime.Heap.Inspect import GHC.Runtime.Context import GHCi.Message import GHCi.RemoteTypes import GHC.ByteCode.Types +import GHC.Linker.Types+import GHC.Linker.Loader as Loader+ import GHC.Hs import GHC.Core.Predicate@@ -217,11 +218,9 @@ -- Turn off -fwarn-unused-local-binds when running a statement, to hide -- warnings about the implicit bindings we introduce.- -- (This is basically `mkInteractiveHscEnv hsc_env`, except we unset- -- -wwarn-unused-local-binds) let ic = hsc_IC hsc_env -- use the interactive dflags idflags' = ic_dflags ic `wopt_unset` Opt_WarnUnusedLocalBinds- hsc_env' = mkInteractiveHscEnv (hsc_env{ hsc_IC = ic{ ic_dflags = idflags' } })+ hsc_env' = mkInteractiveHscEnv (hsc_env{ hsc_IC = ic{ ic_dflags = idflags' }}) r <- liftIO $ hscParsedStmt hsc_env' stmt @@ -388,8 +387,8 @@ = do hsc_env <- getSession let final_ic = extendInteractiveContextWithIds (hsc_IC hsc_env) final_ids final_names = map getName final_ids- dl = hsc_dynLinker hsc_env- liftIO $ Linker.extendLinkEnv dl (zip final_names hvals)+ dl = hsc_loader hsc_env+ liftIO $ Loader.extendLoadedEnv dl (zip final_names hvals) hsc_env' <- liftIO $ rttiEnvironment hsc_env{hsc_IC=final_ic} setSession hsc_env' return (ExecComplete (Right final_names) allocs)@@ -430,8 +429,8 @@ new_names = [ n | thing <- ic_tythings ic , let n = getName thing , not (n `elem` old_names) ]- dl = hsc_dynLinker hsc_env- liftIO $ Linker.deleteFromLinkEnv dl new_names+ dl = hsc_loader hsc_env+ liftIO $ Loader.deleteFromLoadedEnv dl new_names case r of Resume { resumeStmt = expr, resumeContext = fhv@@ -525,9 +524,9 @@ ictxt0 = hsc_IC hsc_env ictxt1 = extendInteractiveContextWithIds ictxt0 [exn_id]- dl = hsc_dynLinker hsc_env+ dl = hsc_loader hsc_env --- Linker.extendLinkEnv dl [(exn_name, apStack)]+ Loader.extendLoadedEnv dl [(exn_name, apStack)] return (hsc_env{ hsc_IC = ictxt1 }, [exn_name], span, "<exception thrown>") -- Just case: we stopped at a breakpoint, we have information about the location@@ -582,11 +581,11 @@ ictxt0 = hsc_IC hsc_env ictxt1 = extendInteractiveContextWithIds ictxt0 final_ids names = map idName new_ids- dl = hsc_dynLinker hsc_env+ dl = hsc_loader hsc_env let fhvs = catMaybes mb_hValues- Linker.extendLinkEnv dl (zip names fhvs)- when result_ok $ Linker.extendLinkEnv dl [(result_name, apStack_fhv)]+ Loader.extendLoadedEnv dl (zip names fhvs)+ when result_ok $ Loader.extendLoadedEnv dl [(result_name, apStack_fhv)] hsc_env1 <- rttiEnvironment hsc_env{ hsc_IC = ictxt1 } return (hsc_env1, if result_ok then result_name:names else names, span, decl) where@@ -1298,13 +1297,13 @@ obtainTermFromId :: HscEnv -> Int -> Bool -> Id -> IO Term obtainTermFromId hsc_env bound force id = do- hv <- Linker.getHValue hsc_env (varName id)+ hv <- Loader.loadName hsc_env (varName id) cvObtainTerm hsc_env bound force (idType id) hv -- Uses RTTI to reconstruct the type of an Id, making it less polymorphic reconstructType :: HscEnv -> Int -> Id -> IO (Maybe Type) reconstructType hsc_env bound id = do- hv <- Linker.getHValue hsc_env (varName id)+ hv <- Loader.loadName hsc_env (varName id) cvReconstructType hsc_env bound (idType id) hv mkRuntimeUnkTyVar :: Name -> Kind -> TyVar
compiler/GHC/Runtime/Heap/Inspect.hs view
@@ -467,6 +467,10 @@ | t == wordPrimTyCon = text $ show (build x :: Word) | t == floatPrimTyCon = text $ show (build x :: Float) | t == doublePrimTyCon = text $ show (build x :: Double)+ | t == int8PrimTyCon = text $ show (build x :: Int8)+ | t == word8PrimTyCon = text $ show (build x :: Word8)+ | t == int16PrimTyCon = text $ show (build x :: Int16)+ | t == word16PrimTyCon = text $ show (build x :: Word16) | t == int32PrimTyCon = text $ show (build x :: Int32) | t == word32PrimTyCon = text $ show (build x :: Word32) | t == int64PrimTyCon = text $ show (build x :: Int64)@@ -1389,4 +1393,4 @@ tyCoVarsOfTypeWellScoped rho , rho) where- (_tvs, rho) = tcSplitForAllTys ty+ (_tvs, rho) = tcSplitForAllInvisTyVars ty
compiler/GHC/Runtime/Interpreter.hs view
@@ -65,9 +65,10 @@ import GHCi.ResolvedBCO import GHCi.BreakArray (BreakArray) import GHC.Runtime.Eval.Types(BreakInfo(..))-import GHC.Runtime.Linker.Types import GHC.ByteCode.Types +import GHC.Linker.Types+ import GHC.Data.Maybe import GHC.Data.FastString @@ -102,7 +103,7 @@ import Data.Array ((!)) import Data.IORef import Foreign hiding (void)-import GHC.Exts.Heap+import qualified GHC.Exts.Heap as Heap import GHC.Stack.CCS (CostCentre,CostCentreStack) import System.Exit import GHC.IO.Handle.Types (Handle)@@ -394,7 +395,7 @@ mb <- iservCmd hsc_env (GetBreakpointVar apStack ix) mapM (mkFinalizedHValue hsc_env) mb -getClosure :: HscEnv -> ForeignHValue -> IO (GenClosure ForeignHValue)+getClosure :: HscEnv -> ForeignHValue -> IO (Heap.GenClosure ForeignHValue) getClosure hsc_env ref = withForeignRef ref $ \hval -> do mb <- iservCmd hsc_env (GetClosure hval)
− compiler/GHC/Runtime/Linker.hs
@@ -1,1802 +0,0 @@-{-# LANGUAGE CPP, NondecreasingIndentation, TupleSections, RecordWildCards #-}-{-# LANGUAGE BangPatterns #-}------- (c) The University of Glasgow 2002-2006------ | The dynamic linker for GHCi.------ This module deals with the top-level issues of dynamic linking,--- calling the object-code linker and the byte-code linker where--- necessary.-module GHC.Runtime.Linker- ( getHValue- , showLinkerState- , linkExpr- , linkDecls- , unload- , withExtendedLinkEnv- , extendLinkEnv- , deleteFromLinkEnv- , extendLoadedPkgs- , linkPackages- , initDynLinker- , linkModule- , linkCmdLineLibs- , uninitializedLinker- )-where--#include "GhclibHsVersions.h"--import GHC.Prelude--import GHC.Platform-import GHC.Platform.Ways--import GHC.Driver.Phases-import GHC.Driver.Env-import GHC.Driver.Session-import GHC.Driver.Ppr--import GHC.Tc.Utils.Monad--import GHC.Runtime.Interpreter-import GHC.Runtime.Interpreter.Types-import GHC.Runtime.Linker.Types-import GHCi.RemoteTypes--import GHC.Iface.Load--import GHC.ByteCode.Linker-import GHC.ByteCode.Asm-import GHC.ByteCode.Types--import GHC.SysTools-import GHC.SysTools.FileCleanup--import GHC.Types.Basic-import GHC.Types.Name-import GHC.Types.Name.Env-import GHC.Types.SrcLoc-import GHC.Types.Unique.DSet--import GHC.Utils.Outputable-import GHC.Utils.Panic-import GHC.Utils.Misc-import GHC.Utils.Error--import GHC.Unit.Finder-import GHC.Unit.Module-import GHC.Unit.Module.ModIface-import GHC.Unit.Module.Deps-import GHC.Unit.Home-import GHC.Unit.Home.ModInfo-import GHC.Unit.State as Packages--import qualified GHC.Data.ShortText as ST-import qualified GHC.Data.Maybe as Maybes-import GHC.Data.FastString-import GHC.Data.List.SetOps---- Standard libraries-import Control.Monad--import qualified Data.Set as Set-import Data.Char (isSpace)-import Data.Function ((&))-import Data.IORef-import Data.List (intercalate, isPrefixOf, isSuffixOf, nub, partition)-import Data.Maybe-import Control.Concurrent.MVar-import qualified Control.Monad.Catch as MC--import System.FilePath-import System.Directory-import System.IO.Unsafe-import System.Environment (lookupEnv)--#if defined(mingw32_HOST_OS)-import System.Win32.Info (getSystemDirectory)-#endif--import GHC.Utils.Exception--{- **********************************************************************-- The Linker's state-- ********************************************************************* -}--{--The persistent linker state *must* match the actual state of the-C dynamic linker at all times.--The MVar used to hold the PersistentLinkerState contains a Maybe-PersistentLinkerState. The MVar serves to ensure mutual exclusion between-multiple loaded copies of the GHC library. The Maybe may be Nothing to-indicate that the linker has not yet been initialised.--The PersistentLinkerState maps Names to actual closures (for-interpreted code only), for use during linking.--}--uninitializedLinker :: IO DynLinker-uninitializedLinker =- newMVar Nothing >>= (pure . DynLinker)--uninitialised :: a-uninitialised = panic "Dynamic linker not initialised"--modifyPLS_ :: DynLinker -> (PersistentLinkerState -> IO PersistentLinkerState) -> IO ()-modifyPLS_ dl f =- modifyMVar_ (dl_mpls dl) (fmap pure . f . fromMaybe uninitialised)--modifyPLS :: DynLinker -> (PersistentLinkerState -> IO (PersistentLinkerState, a)) -> IO a-modifyPLS dl f =- modifyMVar (dl_mpls dl) (fmapFst pure . f . fromMaybe uninitialised)- where fmapFst f = fmap (\(x, y) -> (f x, y))--readPLS :: DynLinker -> IO PersistentLinkerState-readPLS dl =- (fmap (fromMaybe uninitialised) . readMVar) (dl_mpls dl)--modifyMbPLS_- :: DynLinker -> (Maybe PersistentLinkerState -> IO (Maybe PersistentLinkerState)) -> IO ()-modifyMbPLS_ dl f = modifyMVar_ (dl_mpls dl) f--emptyPLS :: PersistentLinkerState-emptyPLS = PersistentLinkerState- { closure_env = emptyNameEnv- , itbl_env = emptyNameEnv- , pkgs_loaded = init_pkgs- , bcos_loaded = []- , objs_loaded = []- , temp_sos = []- }- -- Packages that don't need loading, because the compiler- -- shares them with the interpreted program.- --- -- The linker's symbol table is populated with RTS symbols using an- -- explicit list. See rts/Linker.c for details.- where init_pkgs = [rtsUnitId]--extendLoadedPkgs :: DynLinker -> [UnitId] -> IO ()-extendLoadedPkgs dl pkgs =- modifyPLS_ dl $ \s ->- return s{ pkgs_loaded = pkgs ++ pkgs_loaded s }--extendLinkEnv :: DynLinker -> [(Name,ForeignHValue)] -> IO ()-extendLinkEnv dl new_bindings =- modifyPLS_ dl $ \pls@PersistentLinkerState{..} -> do- let new_ce = extendClosureEnv closure_env new_bindings- return $! pls{ closure_env = new_ce }- -- strictness is important for not retaining old copies of the pls--deleteFromLinkEnv :: DynLinker -> [Name] -> IO ()-deleteFromLinkEnv dl to_remove =- modifyPLS_ dl $ \pls -> do- let ce = closure_env pls- let new_ce = delListFromNameEnv ce to_remove- return pls{ closure_env = new_ce }---- | Get the 'HValue' associated with the given name.------ May cause loading the module that contains the name.------ Throws a 'ProgramError' if loading fails or the name cannot be found.-getHValue :: HscEnv -> Name -> IO ForeignHValue-getHValue hsc_env name = do- let dl = hsc_dynLinker hsc_env- initDynLinker hsc_env- pls <- modifyPLS dl $ \pls -> do- if (isExternalName name) then do- (pls', ok) <- linkDependencies hsc_env pls noSrcSpan- [nameModule name]- if (failed ok) then throwGhcExceptionIO (ProgramError "")- else return (pls', pls')- else- return (pls, pls)- case lookupNameEnv (closure_env pls) name of- Just (_,aa) -> return aa- Nothing- -> ASSERT2(isExternalName name, ppr name)- do let sym_to_find = nameToCLabel name "closure"- m <- lookupClosure hsc_env (unpackFS sym_to_find)- case m of- Just hvref -> mkFinalizedHValue hsc_env hvref- Nothing -> linkFail "GHC.Runtime.Linker.getHValue"- (unpackFS sym_to_find)--linkDependencies :: HscEnv -> PersistentLinkerState- -> SrcSpan -> [Module]- -> IO (PersistentLinkerState, SuccessFlag)-linkDependencies hsc_env pls span needed_mods = do--- initDynLinker (hsc_dflags hsc_env) dl- let hpt = hsc_HPT hsc_env- -- The interpreter and dynamic linker can only handle object code built- -- the "normal" way, i.e. no non-std ways like profiling or ticky-ticky.- -- So here we check the build tag: if we're building a non-standard way- -- then we need to find & link object files built the "normal" way.- maybe_normal_osuf <- checkNonStdWay hsc_env span-- -- Find what packages and linkables are required- (lnks, pkgs) <- getLinkDeps hsc_env hpt pls- maybe_normal_osuf span needed_mods-- -- Link the packages and modules required- pls1 <- linkPackages' hsc_env pkgs pls- linkModules hsc_env pls1 lnks----- | Temporarily extend the linker state.--withExtendedLinkEnv :: (ExceptionMonad m) =>- DynLinker -> [(Name,ForeignHValue)] -> m a -> m a-withExtendedLinkEnv dl new_env action- = MC.bracket (liftIO $ extendLinkEnv dl new_env)- (\_ -> reset_old_env)- (\_ -> action)- where- -- Remember that the linker state might be side-effected- -- during the execution of the IO action, and we don't want to- -- lose those changes (we might have linked a new module or- -- package), so the reset action only removes the names we- -- added earlier.- reset_old_env = liftIO $- modifyPLS_ dl $ \pls ->- let cur = closure_env pls- new = delListFromNameEnv cur (map fst new_env)- in return pls{ closure_env = new }----- | Display the persistent linker state.-showLinkerState :: DynLinker -> IO SDoc-showLinkerState dl- = do pls <- readPLS dl- return $ withPprStyle defaultDumpStyle- (vcat [text "----- Linker state -----",- text "Pkgs:" <+> ppr (pkgs_loaded pls),- text "Objs:" <+> ppr (objs_loaded pls),- text "BCOs:" <+> ppr (bcos_loaded pls)])---{- **********************************************************************-- Initialisation-- ********************************************************************* -}---- | Initialise the dynamic linker. This entails------ a) Calling the C initialisation procedure,------ b) Loading any packages specified on the command line,------ c) Loading any packages specified on the command line, now held in the--- @-l@ options in @v_Opt_l@,------ d) Loading any @.o\/.dll@ files specified on the command line, now held--- in @ldInputs@,------ e) Loading any MacOS frameworks.------ NOTE: This function is idempotent; if called more than once, it does--- nothing. This is useful in Template Haskell, where we call it before--- trying to link.----initDynLinker :: HscEnv -> IO ()-initDynLinker hsc_env = do- let dl = hsc_dynLinker hsc_env- modifyMbPLS_ dl $ \pls -> do- case pls of- Just _ -> return pls- Nothing -> Just <$> reallyInitDynLinker hsc_env--reallyInitDynLinker :: HscEnv -> IO PersistentLinkerState-reallyInitDynLinker hsc_env = do- -- Initialise the linker state- let dflags = hsc_dflags hsc_env- pls0 = emptyPLS-- -- (a) initialise the C dynamic linker- initObjLinker hsc_env-- -- (b) Load packages from the command-line (Note [preload packages])- pls <- linkPackages' hsc_env (preloadUnits (unitState dflags)) pls0-- -- steps (c), (d) and (e)- linkCmdLineLibs' hsc_env pls---linkCmdLineLibs :: HscEnv -> IO ()-linkCmdLineLibs hsc_env = do- let dl = hsc_dynLinker hsc_env- initDynLinker hsc_env- modifyPLS_ dl $ \pls ->- linkCmdLineLibs' hsc_env pls--linkCmdLineLibs' :: HscEnv -> PersistentLinkerState -> IO PersistentLinkerState-linkCmdLineLibs' hsc_env pls =- do- let dflags@(DynFlags { ldInputs = cmdline_ld_inputs- , libraryPaths = lib_paths_base})- = hsc_dflags hsc_env-- -- (c) Link libraries from the command-line- let minus_ls_1 = [ lib | Option ('-':'l':lib) <- cmdline_ld_inputs ]-- -- On Windows we want to add libpthread by default just as GCC would.- -- However because we don't know the actual name of pthread's dll we- -- need to defer this to the locateLib call so we can't initialize it- -- inside of the rts. Instead we do it here to be able to find the- -- import library for pthreads. See #13210.- let platform = targetPlatform dflags- os = platformOS platform- minus_ls = case os of- OSMinGW32 -> "pthread" : minus_ls_1- _ -> minus_ls_1- -- See Note [Fork/Exec Windows]- gcc_paths <- getGCCPaths dflags os-- lib_paths_env <- addEnvPaths "LIBRARY_PATH" lib_paths_base-- maybePutStrLn dflags "Search directories (user):"- maybePutStr dflags (unlines $ map (" "++) lib_paths_env)- maybePutStrLn dflags "Search directories (gcc):"- maybePutStr dflags (unlines $ map (" "++) gcc_paths)-- libspecs- <- mapM (locateLib hsc_env False lib_paths_env gcc_paths) minus_ls-- -- (d) Link .o files from the command-line- classified_ld_inputs <- mapM (classifyLdInput dflags)- [ f | FileOption _ f <- cmdline_ld_inputs ]-- -- (e) Link any MacOS frameworks- let platform = targetPlatform dflags- let (framework_paths, frameworks) =- if platformUsesFrameworks platform- then (frameworkPaths dflags, cmdlineFrameworks dflags)- else ([],[])-- -- Finally do (c),(d),(e)- let cmdline_lib_specs = catMaybes classified_ld_inputs- ++ libspecs- ++ map Framework frameworks- if null cmdline_lib_specs then return pls- else do-- -- Add directories to library search paths, this only has an effect- -- on Windows. On Unix OSes this function is a NOP.- let all_paths = let paths = takeDirectory (pgm_c dflags)- : framework_paths- ++ lib_paths_base- ++ [ takeDirectory dll | DLLPath dll <- libspecs ]- in nub $ map normalise paths- let lib_paths = nub $ lib_paths_base ++ gcc_paths- all_paths_env <- addEnvPaths "LD_LIBRARY_PATH" all_paths- pathCache <- mapM (addLibrarySearchPath hsc_env) all_paths_env-- let merged_specs = mergeStaticObjects cmdline_lib_specs- pls1 <- foldM (preloadLib hsc_env lib_paths framework_paths) pls- merged_specs-- maybePutStr dflags "final link ... "- ok <- resolveObjs hsc_env-- -- DLLs are loaded, reset the search paths- mapM_ (removeLibrarySearchPath hsc_env) $ reverse pathCache-- if succeeded ok then maybePutStrLn dflags "done"- else throwGhcExceptionIO (ProgramError "linking extra libraries/objects failed")-- return pls1---- | Merge runs of consecutive of 'Objects'. This allows for resolution of--- cyclic symbol references when dynamically linking. Specifically, we link--- together all of the static objects into a single shared object, avoiding--- the issue we saw in #13786.-mergeStaticObjects :: [LibrarySpec] -> [LibrarySpec]-mergeStaticObjects specs = go [] specs- where- go :: [FilePath] -> [LibrarySpec] -> [LibrarySpec]- go accum (Objects objs : rest) = go (objs ++ accum) rest- go accum@(_:_) rest = Objects (reverse accum) : go [] rest- go [] (spec:rest) = spec : go [] rest- go [] [] = []--{- Note [preload packages]--Why do we need to preload packages from the command line? This is an-explanation copied from #2437:--I tried to implement the suggestion from #3560, thinking it would be-easy, but there are two reasons we link in packages eagerly when they-are mentioned on the command line:-- * So that you can link in extra object files or libraries that- depend on the packages. e.g. ghc -package foo -lbar where bar is a- C library that depends on something in foo. So we could link in- foo eagerly if and only if there are extra C libs or objects to- link in, but....-- * Haskell code can depend on a C function exported by a package, and- the normal dependency tracking that TH uses can't know about these- dependencies. The test ghcilink004 relies on this, for example.--I conclude that we need two -package flags: one that says "this is a-package I want to make available", and one that says "this is a-package I want to link in eagerly". Would that be too complicated for-users?--}--classifyLdInput :: DynFlags -> FilePath -> IO (Maybe LibrarySpec)-classifyLdInput dflags f- | isObjectFilename platform f = return (Just (Objects [f]))- | isDynLibFilename platform f = return (Just (DLLPath f))- | otherwise = do- putLogMsg dflags NoReason SevInfo noSrcSpan- $ withPprStyle defaultUserStyle- (text ("Warning: ignoring unrecognised input `" ++ f ++ "'"))- return Nothing- where platform = targetPlatform dflags--preloadLib- :: HscEnv -> [String] -> [String] -> PersistentLinkerState- -> LibrarySpec -> IO PersistentLinkerState-preloadLib hsc_env lib_paths framework_paths pls lib_spec = do- maybePutStr dflags ("Loading object " ++ showLS lib_spec ++ " ... ")- case lib_spec of- Objects static_ishs -> do- (b, pls1) <- preload_statics lib_paths static_ishs- maybePutStrLn dflags (if b then "done" else "not found")- return pls1-- Archive static_ish -> do- b <- preload_static_archive lib_paths static_ish- maybePutStrLn dflags (if b then "done" else "not found")- return pls-- DLL dll_unadorned -> do- maybe_errstr <- loadDLL hsc_env (platformSOName platform dll_unadorned)- case maybe_errstr of- Nothing -> maybePutStrLn dflags "done"- Just mm | platformOS platform /= OSDarwin ->- preloadFailed mm lib_paths lib_spec- Just mm | otherwise -> do- -- As a backup, on Darwin, try to also load a .so file- -- since (apparently) some things install that way - see- -- ticket #8770.- let libfile = ("lib" ++ dll_unadorned) <.> "so"- err2 <- loadDLL hsc_env libfile- case err2 of- Nothing -> maybePutStrLn dflags "done"- Just _ -> preloadFailed mm lib_paths lib_spec- return pls-- DLLPath dll_path -> do- do maybe_errstr <- loadDLL hsc_env dll_path- case maybe_errstr of- Nothing -> maybePutStrLn dflags "done"- Just mm -> preloadFailed mm lib_paths lib_spec- return pls-- Framework framework ->- if platformUsesFrameworks (targetPlatform dflags)- then do maybe_errstr <- loadFramework hsc_env framework_paths framework- case maybe_errstr of- Nothing -> maybePutStrLn dflags "done"- Just mm -> preloadFailed mm framework_paths lib_spec- return pls- else throwGhcExceptionIO (ProgramError "preloadLib Framework")-- where- dflags = hsc_dflags hsc_env-- platform = targetPlatform dflags-- preloadFailed :: String -> [String] -> LibrarySpec -> IO ()- preloadFailed sys_errmsg paths spec- = do maybePutStr dflags "failed.\n"- throwGhcExceptionIO $- CmdLineError (- "user specified .o/.so/.DLL could not be loaded ("- ++ sys_errmsg ++ ")\nWhilst trying to load: "- ++ showLS spec ++ "\nAdditional directories searched:"- ++ (if null paths then " (none)" else- intercalate "\n" (map (" "++) paths)))-- -- Not interested in the paths in the static case.- preload_statics _paths names- = do b <- or <$> mapM doesFileExist names- if not b then return (False, pls)- else if hostIsDynamic- then do pls1 <- dynLoadObjs hsc_env pls names- return (True, pls1)- else do mapM_ (loadObj hsc_env) names- return (True, pls)-- preload_static_archive _paths name- = do b <- doesFileExist name- if not b then return False- else do if hostIsDynamic- then throwGhcExceptionIO $- CmdLineError dynamic_msg- else loadArchive hsc_env name- return True- where- dynamic_msg = unlines- [ "User-specified static library could not be loaded ("- ++ name ++ ")"- , "Loading static libraries is not supported in this configuration."- , "Try using a dynamic library instead."- ]---{- **********************************************************************-- Link a byte-code expression-- ********************************************************************* -}---- | Link a single expression, /including/ first linking packages and--- modules that this expression depends on.------ Raises an IO exception ('ProgramError') if it can't find a compiled--- version of the dependents to link.----linkExpr :: HscEnv -> SrcSpan -> UnlinkedBCO -> IO ForeignHValue-linkExpr hsc_env span root_ul_bco- = do {- -- Initialise the linker (if it's not been done already)- ; initDynLinker hsc_env-- -- Extract the DynLinker value for passing into required places- ; let dl = hsc_dynLinker hsc_env-- -- Take lock for the actual work.- ; modifyPLS dl $ \pls0 -> do {-- -- Link the packages and modules required- ; (pls, ok) <- linkDependencies hsc_env pls0 span needed_mods- ; if failed ok then- throwGhcExceptionIO (ProgramError "")- else do {-- -- Link the expression itself- let ie = itbl_env pls- ce = closure_env pls-- -- Link the necessary packages and linkables-- ; let nobreakarray = error "no break array"- bco_ix = mkNameEnv [(unlinkedBCOName root_ul_bco, 0)]- ; resolved <- linkBCO hsc_env ie ce bco_ix nobreakarray root_ul_bco- ; [root_hvref] <- createBCOs hsc_env [resolved]- ; fhv <- mkFinalizedHValue hsc_env root_hvref- ; return (pls, fhv)- }}}- where- free_names = uniqDSetToList (bcoFreeNames root_ul_bco)-- needed_mods :: [Module]- needed_mods = [ nameModule n | n <- free_names,- isExternalName n, -- Names from other modules- not (isWiredInName n) -- Exclude wired-in names- ] -- (see note below)- -- Exclude wired-in names because we may not have read- -- their interface files, so getLinkDeps will fail- -- All wired-in names are in the base package, which we link- -- by default, so we can safely ignore them here.--dieWith :: DynFlags -> SrcSpan -> MsgDoc -> IO a-dieWith dflags span msg = throwGhcExceptionIO (ProgramError (showSDoc dflags (mkLocMessage SevFatal span msg)))---checkNonStdWay :: HscEnv -> SrcSpan -> IO (Maybe FilePath)-checkNonStdWay hsc_env srcspan- | Just (ExternalInterp {}) <- hsc_interp hsc_env = return Nothing- -- with -fexternal-interpreter we load the .o files, whatever way- -- they were built. If they were built for a non-std way, then- -- we will use the appropriate variant of the iserv binary to load them.-- | hostFullWays == targetFullWays = return Nothing- -- Only if we are compiling with the same ways as GHC is built- -- with, can we dynamically load those object files. (see #3604)-- | objectSuf (hsc_dflags hsc_env) == normalObjectSuffix && not (null targetFullWays)- = failNonStd (hsc_dflags hsc_env) srcspan-- | otherwise = return (Just (hostWayTag ++ "o"))- where- targetFullWays = fullWays (ways (hsc_dflags hsc_env))- hostWayTag = case waysTag hostFullWays of- "" -> ""- tag -> tag ++ "_"--normalObjectSuffix :: String-normalObjectSuffix = phaseInputExt StopLn--failNonStd :: DynFlags -> SrcSpan -> IO (Maybe FilePath)-failNonStd dflags srcspan = dieWith dflags srcspan $- text "Cannot load" <+> compWay <+>- text "objects when GHC is built" <+> ghciWay $$- text "To fix this, either:" $$- text " (1) Use -fexternal-interpreter, or" $$- text " (2) Build the program twice: once" <+>- ghciWay <> text ", and then" $$- text " with" <+> compWay <+>- text "using -osuf to set a different object file suffix."- where compWay- | WayDyn `elem` ways dflags = text "-dynamic"- | WayProf `elem` ways dflags = text "-prof"- | otherwise = text "normal"- ghciWay- | hostIsDynamic = text "with -dynamic"- | hostIsProfiled = text "with -prof"- | otherwise = text "the normal way"--getLinkDeps :: HscEnv -> HomePackageTable- -> PersistentLinkerState- -> Maybe FilePath -- replace object suffices?- -> SrcSpan -- for error messages- -> [Module] -- If you need these- -> IO ([Linkable], [UnitId]) -- ... then link these first--- Fails with an IO exception if it can't find enough files--getLinkDeps hsc_env hpt pls replace_osuf span mods--- Find all the packages and linkables that a set of modules depends on- = do {- -- 1. Find the dependent home-pkg-modules/packages from each iface- -- (omitting modules from the interactive package, which is already linked)- ; (mods_s, pkgs_s) <- follow_deps (filterOut isInteractiveModule mods)- emptyUniqDSet emptyUniqDSet;-- ; let {- -- 2. Exclude ones already linked- -- Main reason: avoid findModule calls in get_linkable- mods_needed = mods_s `minusList` linked_mods ;- pkgs_needed = pkgs_s `minusList` pkgs_loaded pls ;-- linked_mods = map (moduleName.linkableModule)- (objs_loaded pls ++ bcos_loaded pls) }-- -- 3. For each dependent module, find its linkable- -- This will either be in the HPT or (in the case of one-shot- -- compilation) we may need to use maybe_getFileLinkable- ; let { osuf = objectSuf dflags }- ; lnks_needed <- mapM (get_linkable osuf) mods_needed-- ; return (lnks_needed, pkgs_needed) }- where- dflags = hsc_dflags hsc_env-- -- The ModIface contains the transitive closure of the module dependencies- -- within the current package, *except* for boot modules: if we encounter- -- a boot module, we have to find its real interface and discover the- -- dependencies of that. Hence we need to traverse the dependency- -- tree recursively. See bug #936, testcase ghci/prog007.- follow_deps :: [Module] -- modules to follow- -> UniqDSet ModuleName -- accum. module dependencies- -> UniqDSet UnitId -- accum. package dependencies- -> IO ([ModuleName], [UnitId]) -- result- follow_deps [] acc_mods acc_pkgs- = return (uniqDSetToList acc_mods, uniqDSetToList acc_pkgs)- follow_deps (mod:mods) acc_mods acc_pkgs- = do- mb_iface <- initIfaceCheck (text "getLinkDeps") hsc_env $- loadInterface msg mod (ImportByUser NotBoot)- iface <- case mb_iface of- Maybes.Failed err -> throwGhcExceptionIO (ProgramError (showSDoc dflags err))- Maybes.Succeeded iface -> return iface-- when (mi_boot iface == IsBoot) $ link_boot_mod_error mod-- let- pkg = moduleUnit mod- deps = mi_deps iface- home_unit = hsc_home_unit hsc_env-- pkg_deps = dep_pkgs deps- (boot_deps, mod_deps) = flip partitionWith (dep_mods deps) $- \ (GWIB { gwib_mod = m, gwib_isBoot = is_boot }) ->- m & case is_boot of- IsBoot -> Left- NotBoot -> Right-- boot_deps' = filter (not . (`elementOfUniqDSet` acc_mods)) boot_deps- acc_mods' = addListToUniqDSet acc_mods (moduleName mod : mod_deps)- acc_pkgs' = addListToUniqDSet acc_pkgs $ map fst pkg_deps- --- if not (isHomeUnit home_unit pkg)- then follow_deps mods acc_mods (addOneToUniqDSet acc_pkgs' (toUnitId pkg))- else follow_deps (map (mkHomeModule home_unit) boot_deps' ++ mods)- acc_mods' acc_pkgs'- where- msg = text "need to link module" <+> ppr mod <+>- text "due to use of Template Haskell"--- link_boot_mod_error mod =- throwGhcExceptionIO (ProgramError (showSDoc dflags (- text "module" <+> ppr mod <+>- text "cannot be linked; it is only available as a boot module")))-- no_obj :: Outputable a => a -> IO b- no_obj mod = dieWith dflags span $- text "cannot find object file for module " <>- quotes (ppr mod) $$- while_linking_expr-- while_linking_expr = text "while linking an interpreted expression"-- -- This one is a build-system bug-- get_linkable osuf mod_name -- A home-package module- | Just mod_info <- lookupHpt hpt mod_name- = adjust_linkable (Maybes.expectJust "getLinkDeps" (hm_linkable mod_info))- | otherwise- = do -- It's not in the HPT because we are in one shot mode,- -- so use the Finder to get a ModLocation...- mb_stuff <- findHomeModule hsc_env mod_name- case mb_stuff of- Found loc mod -> found loc mod- _ -> no_obj mod_name- where- found loc mod = do {- -- ...and then find the linkable for it- mb_lnk <- findObjectLinkableMaybe mod loc ;- case mb_lnk of {- Nothing -> no_obj mod ;- Just lnk -> adjust_linkable lnk- }}-- adjust_linkable lnk- | Just new_osuf <- replace_osuf = do- new_uls <- mapM (adjust_ul new_osuf)- (linkableUnlinked lnk)- return lnk{ linkableUnlinked=new_uls }- | otherwise =- return lnk-- adjust_ul new_osuf (DotO file) = do- MASSERT(osuf `isSuffixOf` file)- let file_base = fromJust (stripExtension osuf file)- new_file = file_base <.> new_osuf- ok <- doesFileExist new_file- if (not ok)- then dieWith dflags span $- text "cannot find object file "- <> quotes (text new_file) $$ while_linking_expr- else return (DotO new_file)- adjust_ul _ (DotA fp) = panic ("adjust_ul DotA " ++ show fp)- adjust_ul _ (DotDLL fp) = panic ("adjust_ul DotDLL " ++ show fp)- adjust_ul _ l@(BCOs {}) = return l----{- **********************************************************************-- Loading a Decls statement-- ********************************************************************* -}--linkDecls :: HscEnv -> SrcSpan -> CompiledByteCode -> IO ()-linkDecls hsc_env span cbc@CompiledByteCode{..} = do- -- Initialise the linker (if it's not been done already)- initDynLinker hsc_env-- -- Extract the DynLinker for passing into required places- let dl = hsc_dynLinker hsc_env-- -- Take lock for the actual work.- modifyPLS dl $ \pls0 -> do-- -- Link the packages and modules required- (pls, ok) <- linkDependencies hsc_env pls0 span needed_mods- if failed ok- then throwGhcExceptionIO (ProgramError "")- else do-- -- Link the expression itself- let ie = plusNameEnv (itbl_env pls) bc_itbls- ce = closure_env pls-- -- Link the necessary packages and linkables- new_bindings <- linkSomeBCOs hsc_env ie ce [cbc]- nms_fhvs <- makeForeignNamedHValueRefs hsc_env new_bindings- let pls2 = pls { closure_env = extendClosureEnv ce nms_fhvs- , itbl_env = ie }- return (pls2, ())- where- free_names = uniqDSetToList $- foldr (unionUniqDSets . bcoFreeNames) emptyUniqDSet bc_bcos-- needed_mods :: [Module]- needed_mods = [ nameModule n | n <- free_names,- isExternalName n, -- Names from other modules- not (isWiredInName n) -- Exclude wired-in names- ] -- (see note below)- -- Exclude wired-in names because we may not have read- -- their interface files, so getLinkDeps will fail- -- All wired-in names are in the base package, which we link- -- by default, so we can safely ignore them here.--{- **********************************************************************-- Loading a single module-- ********************************************************************* -}--linkModule :: HscEnv -> Module -> IO ()-linkModule hsc_env mod = do- initDynLinker hsc_env- let dl = hsc_dynLinker hsc_env- modifyPLS_ dl $ \pls -> do- (pls', ok) <- linkDependencies hsc_env pls noSrcSpan [mod]- if (failed ok) then throwGhcExceptionIO (ProgramError "could not link module")- else return pls'--{- **********************************************************************-- Link some linkables- The linkables may consist of a mixture of- byte-code modules and object modules-- ********************************************************************* -}--linkModules :: HscEnv -> PersistentLinkerState -> [Linkable]- -> IO (PersistentLinkerState, SuccessFlag)-linkModules hsc_env pls linkables- = mask_ $ do -- don't want to be interrupted by ^C in here-- let (objs, bcos) = partition isObjectLinkable- (concatMap partitionLinkable linkables)-- -- Load objects first; they can't depend on BCOs- (pls1, ok_flag) <- dynLinkObjs hsc_env pls objs-- if failed ok_flag then- return (pls1, Failed)- else do- pls2 <- dynLinkBCOs hsc_env pls1 bcos- return (pls2, Succeeded)----- HACK to support f-x-dynamic in the interpreter; no other purpose-partitionLinkable :: Linkable -> [Linkable]-partitionLinkable li- = let li_uls = linkableUnlinked li- li_uls_obj = filter isObject li_uls- li_uls_bco = filter isInterpretable li_uls- in- case (li_uls_obj, li_uls_bco) of- (_:_, _:_) -> [li {linkableUnlinked=li_uls_obj},- li {linkableUnlinked=li_uls_bco}]- _ -> [li]--findModuleLinkable_maybe :: [Linkable] -> Module -> Maybe Linkable-findModuleLinkable_maybe lis mod- = case [LM time nm us | LM time nm us <- lis, nm == mod] of- [] -> Nothing- [li] -> Just li- _ -> pprPanic "findModuleLinkable" (ppr mod)--linkableInSet :: Linkable -> [Linkable] -> Bool-linkableInSet l objs_loaded =- case findModuleLinkable_maybe objs_loaded (linkableModule l) of- Nothing -> False- Just m -> linkableTime l == linkableTime m---{- **********************************************************************-- The object-code linker-- ********************************************************************* -}--dynLinkObjs :: HscEnv -> PersistentLinkerState -> [Linkable]- -> IO (PersistentLinkerState, SuccessFlag)-dynLinkObjs hsc_env pls objs = do- -- Load the object files and link them- let (objs_loaded', new_objs) = rmDupLinkables (objs_loaded pls) objs- pls1 = pls { objs_loaded = objs_loaded' }- unlinkeds = concatMap linkableUnlinked new_objs- wanted_objs = map nameOfObject unlinkeds-- if interpreterDynamic (hscInterp hsc_env)- then do pls2 <- dynLoadObjs hsc_env pls1 wanted_objs- return (pls2, Succeeded)- else do mapM_ (loadObj hsc_env) wanted_objs-- -- Link them all together- ok <- resolveObjs hsc_env-- -- If resolving failed, unload all our- -- object modules and carry on- if succeeded ok then- return (pls1, Succeeded)- else do- pls2 <- unload_wkr hsc_env [] pls1- return (pls2, Failed)---dynLoadObjs :: HscEnv -> PersistentLinkerState -> [FilePath]- -> IO PersistentLinkerState-dynLoadObjs _ pls [] = return pls-dynLoadObjs hsc_env pls@PersistentLinkerState{..} objs = do- let dflags = hsc_dflags hsc_env- let platform = targetPlatform dflags- let minus_ls = [ lib | Option ('-':'l':lib) <- ldInputs dflags ]- let minus_big_ls = [ lib | Option ('-':'L':lib) <- ldInputs dflags ]- (soFile, libPath , libName) <-- newTempLibName dflags TFL_CurrentModule (platformSOExt platform)- let- dflags2 = dflags {- -- We don't want the original ldInputs in- -- (they're already linked in), but we do want- -- to link against previous dynLoadObjs- -- libraries if there were any, so that the linker- -- can resolve dependencies when it loads this- -- library.- ldInputs =- concatMap (\l -> [ Option ("-l" ++ l) ])- (nub $ snd <$> temp_sos)- ++ concatMap (\lp -> Option ("-L" ++ lp)- : if gopt Opt_RPath dflags- then [ Option "-Xlinker"- , Option "-rpath"- , Option "-Xlinker"- , Option lp ]- else [])- (nub $ fst <$> temp_sos)- ++ concatMap- (\lp -> Option ("-L" ++ lp)- : if gopt Opt_RPath dflags- then [ Option "-Xlinker"- , Option "-rpath"- , Option "-Xlinker"- , Option lp ]- else [])- minus_big_ls- -- See Note [-Xlinker -rpath vs -Wl,-rpath]- ++ map (\l -> Option ("-l" ++ l)) minus_ls,- -- Add -l options and -L options from dflags.- --- -- When running TH for a non-dynamic way, we still- -- need to make -l flags to link against the dynamic- -- libraries, so we need to add WayDyn to ways.- --- -- Even if we're e.g. profiling, we still want- -- the vanilla dynamic libraries, so we set the- -- ways / build tag to be just WayDyn.- ways = Set.singleton WayDyn,- outputFile = Just soFile- }- -- link all "loaded packages" so symbols in those can be resolved- -- Note: We are loading packages with local scope, so to see the- -- symbols in this link we must link all loaded packages again.- linkDynLib dflags2 objs pkgs_loaded-- -- if we got this far, extend the lifetime of the library file- changeTempFilesLifetime dflags TFL_GhcSession [soFile]- m <- loadDLL hsc_env soFile- case m of- Nothing -> return $! pls { temp_sos = (libPath, libName) : temp_sos }- Just err -> linkFail msg err- where- msg = "GHC.Runtime.Linker.dynLoadObjs: Loading temp shared object failed"--rmDupLinkables :: [Linkable] -- Already loaded- -> [Linkable] -- New linkables- -> ([Linkable], -- New loaded set (including new ones)- [Linkable]) -- New linkables (excluding dups)-rmDupLinkables already ls- = go already [] ls- where- go already extras [] = (already, extras)- go already extras (l:ls)- | linkableInSet l already = go already extras ls- | otherwise = go (l:already) (l:extras) ls--{- **********************************************************************-- The byte-code linker-- ********************************************************************* -}---dynLinkBCOs :: HscEnv -> PersistentLinkerState -> [Linkable]- -> IO PersistentLinkerState-dynLinkBCOs hsc_env pls bcos = do-- let (bcos_loaded', new_bcos) = rmDupLinkables (bcos_loaded pls) bcos- pls1 = pls { bcos_loaded = bcos_loaded' }- unlinkeds :: [Unlinked]- unlinkeds = concatMap linkableUnlinked new_bcos-- cbcs :: [CompiledByteCode]- cbcs = map byteCodeOfObject unlinkeds--- ies = map bc_itbls cbcs- gce = closure_env pls- final_ie = foldr plusNameEnv (itbl_env pls) ies-- names_and_refs <- linkSomeBCOs hsc_env final_ie gce cbcs-- -- We only want to add the external ones to the ClosureEnv- let (to_add, to_drop) = partition (isExternalName.fst) names_and_refs-- -- Immediately release any HValueRefs we're not going to add- freeHValueRefs hsc_env (map snd to_drop)- -- Wrap finalizers on the ones we want to keep- new_binds <- makeForeignNamedHValueRefs hsc_env to_add-- return pls1 { closure_env = extendClosureEnv gce new_binds,- itbl_env = final_ie }---- Link a bunch of BCOs and return references to their values-linkSomeBCOs :: HscEnv- -> ItblEnv- -> ClosureEnv- -> [CompiledByteCode]- -> IO [(Name,HValueRef)]- -- The returned HValueRefs are associated 1-1 with- -- the incoming unlinked BCOs. Each gives the- -- value of the corresponding unlinked BCO--linkSomeBCOs hsc_env ie ce mods = foldr fun do_link mods []- where- fun CompiledByteCode{..} inner accum =- case bc_breaks of- Nothing -> inner ((panic "linkSomeBCOs: no break array", bc_bcos) : accum)- Just mb -> withForeignRef (modBreaks_flags mb) $ \breakarray ->- inner ((breakarray, bc_bcos) : accum)-- do_link [] = return []- do_link mods = do- let flat = [ (breakarray, bco) | (breakarray, bcos) <- mods, bco <- bcos ]- names = map (unlinkedBCOName . snd) flat- bco_ix = mkNameEnv (zip names [0..])- resolved <- sequence [ linkBCO hsc_env ie ce bco_ix breakarray bco- | (breakarray, bco) <- flat ]- hvrefs <- createBCOs hsc_env resolved- return (zip names hvrefs)---- | Useful to apply to the result of 'linkSomeBCOs'-makeForeignNamedHValueRefs- :: HscEnv -> [(Name,HValueRef)] -> IO [(Name,ForeignHValue)]-makeForeignNamedHValueRefs hsc_env bindings =- mapM (\(n, hvref) -> (n,) <$> mkFinalizedHValue hsc_env hvref) bindings--{- **********************************************************************-- Unload some object modules-- ********************************************************************* -}---- ------------------------------------------------------------------------------ | Unloading old objects ready for a new compilation sweep.------ The compilation manager provides us with a list of linkables that it--- considers \"stable\", i.e. won't be recompiled this time around. For--- each of the modules current linked in memory,------ * if the linkable is stable (and it's the same one -- the user may have--- recompiled the module on the side), we keep it,------ * otherwise, we unload it.------ * we also implicitly unload all temporary bindings at this point.----unload :: HscEnv- -> [Linkable] -- ^ The linkables to *keep*.- -> IO ()-unload hsc_env linkables- = mask_ $ do -- mask, so we're safe from Ctrl-C in here-- -- Initialise the linker (if it's not been done already)- initDynLinker hsc_env-- -- Extract DynLinker for passing into required places- let dl = hsc_dynLinker hsc_env-- new_pls- <- modifyPLS dl $ \pls -> do- pls1 <- unload_wkr hsc_env linkables pls- return (pls1, pls1)-- let dflags = hsc_dflags hsc_env- debugTraceMsg dflags 3 $- text "unload: retaining objs" <+> ppr (objs_loaded new_pls)- debugTraceMsg dflags 3 $- text "unload: retaining bcos" <+> ppr (bcos_loaded new_pls)- return ()--unload_wkr :: HscEnv- -> [Linkable] -- stable linkables- -> PersistentLinkerState- -> IO PersistentLinkerState--- Does the core unload business--- (the wrapper blocks exceptions and deals with the PLS get and put)--unload_wkr hsc_env keep_linkables pls@PersistentLinkerState{..} = do- -- NB. careful strictness here to avoid keeping the old PLS when- -- we're unloading some code. -fghci-leak-check with the tests in- -- testsuite/ghci can detect space leaks here.-- let (objs_to_keep, bcos_to_keep) = partition isObjectLinkable keep_linkables-- discard keep l = not (linkableInSet l keep)-- (objs_to_unload, remaining_objs_loaded) =- partition (discard objs_to_keep) objs_loaded- (bcos_to_unload, remaining_bcos_loaded) =- partition (discard bcos_to_keep) bcos_loaded-- mapM_ unloadObjs objs_to_unload- mapM_ unloadObjs bcos_to_unload-- -- If we unloaded any object files at all, we need to purge the cache- -- of lookupSymbol results.- when (not (null (objs_to_unload ++- filter (not . null . linkableObjs) bcos_to_unload))) $- purgeLookupSymbolCache hsc_env-- let !bcos_retained = mkModuleSet $ map linkableModule remaining_bcos_loaded-- -- Note that we want to remove all *local*- -- (i.e. non-isExternal) names too (these are the- -- temporary bindings from the command line).- keep_name :: (Name, a) -> Bool- keep_name (n,_) = isExternalName n &&- nameModule n `elemModuleSet` bcos_retained-- itbl_env' = filterNameEnv keep_name itbl_env- closure_env' = filterNameEnv keep_name closure_env-- !new_pls = pls { itbl_env = itbl_env',- closure_env = closure_env',- bcos_loaded = remaining_bcos_loaded,- objs_loaded = remaining_objs_loaded }-- return new_pls- where- unloadObjs :: Linkable -> IO ()- unloadObjs lnk- | hostIsDynamic = return ()- -- We don't do any cleanup when linking objects with the- -- dynamic linker. Doing so introduces extra complexity for- -- not much benefit.-- -- Code unloading currently disabled due to instability.- -- See #16841.- -- id False, so that the pattern-match checker doesn't complain- | id False -- otherwise- = mapM_ (unloadObj hsc_env) [f | DotO f <- linkableUnlinked lnk]- -- The components of a BCO linkable may contain- -- dot-o files. Which is very confusing.- --- -- But the BCO parts can be unlinked just by- -- letting go of them (plus of course depopulating- -- the symbol table which is done in the main body)- | otherwise = return () -- see #16841--{- **********************************************************************-- Loading packages-- ********************************************************************* -}--data LibrarySpec- = Objects [FilePath] -- Full path names of set of .o files, including trailing .o- -- We allow batched loading to ensure that cyclic symbol- -- references can be resolved (see #13786).- -- For dynamic objects only, try to find the object- -- file in all the directories specified in- -- v_Library_paths before giving up.-- | Archive FilePath -- Full path name of a .a file, including trailing .a-- | DLL String -- "Unadorned" name of a .DLL/.so- -- e.g. On unix "qt" denotes "libqt.so"- -- On Windows "burble" denotes "burble.DLL" or "libburble.dll"- -- loadDLL is platform-specific and adds the lib/.so/.DLL- -- suffixes platform-dependently-- | DLLPath FilePath -- Absolute or relative pathname to a dynamic library- -- (ends with .dll or .so).-- | Framework String -- Only used for darwin, but does no harm--instance Outputable LibrarySpec where- ppr (Objects objs) = text "Objects" <+> ppr objs- ppr (Archive a) = text "Archive" <+> text a- ppr (DLL s) = text "DLL" <+> text s- ppr (DLLPath f) = text "DLLPath" <+> text f- ppr (Framework s) = text "Framework" <+> text s---- If this package is already part of the GHCi binary, we'll already--- have the right DLLs for this package loaded, so don't try to--- load them again.------ But on Win32 we must load them 'again'; doing so is a harmless no-op--- as far as the loader is concerned, but it does initialise the list--- of DLL handles that rts/Linker.c maintains, and that in turn is--- used by lookupSymbol. So we must call addDLL for each library--- just to get the DLL handle into the list.-partOfGHCi :: [PackageName]-partOfGHCi- | isWindowsHost || isDarwinHost = []- | otherwise = map (PackageName . mkFastString)- ["base", "template-haskell", "editline"]--showLS :: LibrarySpec -> String-showLS (Objects nms) = "(static) [" ++ intercalate ", " nms ++ "]"-showLS (Archive nm) = "(static archive) " ++ nm-showLS (DLL nm) = "(dynamic) " ++ nm-showLS (DLLPath nm) = "(dynamic) " ++ nm-showLS (Framework nm) = "(framework) " ++ nm---- | Link exactly the specified packages, and their dependents (unless of--- course they are already linked). The dependents are linked--- automatically, and it doesn't matter what order you specify the input--- packages.----linkPackages :: HscEnv -> [UnitId] -> IO ()--- NOTE: in fact, since each module tracks all the packages it depends on,--- we don't really need to use the package-config dependencies.------ However we do need the package-config stuff (to find aux libs etc),--- and following them lets us load libraries in the right order, which--- perhaps makes the error message a bit more localised if we get a link--- failure. So the dependency walking code is still here.--linkPackages hsc_env new_pkgs = do- -- It's probably not safe to try to load packages concurrently, so we take- -- a lock.- initDynLinker hsc_env- let dl = hsc_dynLinker hsc_env- modifyPLS_ dl $ \pls ->- linkPackages' hsc_env new_pkgs pls--linkPackages' :: HscEnv -> [UnitId] -> PersistentLinkerState- -> IO PersistentLinkerState-linkPackages' hsc_env new_pks pls = do- pkgs' <- link (pkgs_loaded pls) new_pks- return $! pls { pkgs_loaded = pkgs' }- where- dflags = hsc_dflags hsc_env- pkgstate = unitState dflags-- link :: [UnitId] -> [UnitId] -> IO [UnitId]- link pkgs new_pkgs =- foldM link_one pkgs new_pkgs-- link_one pkgs new_pkg- | new_pkg `elem` pkgs -- Already linked- = return pkgs-- | Just pkg_cfg <- lookupUnitId pkgstate new_pkg- = do { -- Link dependents first- pkgs' <- link pkgs (unitDepends pkg_cfg)- -- Now link the package itself- ; linkPackage hsc_env pkg_cfg- ; return (new_pkg : pkgs') }-- | otherwise- = throwGhcExceptionIO (CmdLineError ("unknown package: " ++ unpackFS (unitIdFS new_pkg)))---linkPackage :: HscEnv -> UnitInfo -> IO ()-linkPackage hsc_env pkg- = do- let dflags = hsc_dflags hsc_env- platform = targetPlatform dflags- is_dyn = interpreterDynamic (hscInterp hsc_env)- dirs | is_dyn = map ST.unpack $ Packages.unitLibraryDynDirs pkg- | otherwise = map ST.unpack $ Packages.unitLibraryDirs pkg-- let hs_libs = map ST.unpack $ Packages.unitLibraries pkg- -- The FFI GHCi import lib isn't needed as- -- GHC.Runtime.Linker + rts/Linker.c link the- -- interpreted references to FFI to the compiled FFI.- -- We therefore filter it out so that we don't get- -- duplicate symbol errors.- hs_libs' = filter ("HSffi" /=) hs_libs-- -- Because of slight differences between the GHC dynamic linker and- -- the native system linker some packages have to link with a- -- different list of libraries when using GHCi. Examples include: libs- -- that are actually gnu ld scripts, and the possibility that the .a- -- libs do not exactly match the .so/.dll equivalents. So if the- -- package file provides an "extra-ghci-libraries" field then we use- -- that instead of the "extra-libraries" field.- extdeplibs = map ST.unpack (if null (Packages.unitExtDepLibsGhc pkg)- then Packages.unitExtDepLibsSys pkg- else Packages.unitExtDepLibsGhc pkg)- linkerlibs = [ lib | '-':'l':lib <- (map ST.unpack $ Packages.unitLinkerOptions pkg) ]- extra_libs = extdeplibs ++ linkerlibs-- -- See Note [Fork/Exec Windows]- gcc_paths <- getGCCPaths dflags (platformOS platform)- dirs_env <- addEnvPaths "LIBRARY_PATH" dirs-- hs_classifieds- <- mapM (locateLib hsc_env True dirs_env gcc_paths) hs_libs'- extra_classifieds- <- mapM (locateLib hsc_env False dirs_env gcc_paths) extra_libs- let classifieds = hs_classifieds ++ extra_classifieds-- -- Complication: all the .so's must be loaded before any of the .o's.- let known_dlls = [ dll | DLLPath dll <- classifieds ]- dlls = [ dll | DLL dll <- classifieds ]- objs = [ obj | Objects objs <- classifieds- , obj <- objs ]- archs = [ arch | Archive arch <- classifieds ]-- -- Add directories to library search paths- let dll_paths = map takeDirectory known_dlls- all_paths = nub $ map normalise $ dll_paths ++ dirs- all_paths_env <- addEnvPaths "LD_LIBRARY_PATH" all_paths- pathCache <- mapM (addLibrarySearchPath hsc_env) all_paths_env-- maybePutSDoc dflags- (text "Loading unit " <> pprUnitInfoForUser pkg <> text " ... ")-- -- See comments with partOfGHCi-#if defined(CAN_LOAD_DLL)- when (unitPackageName pkg `notElem` partOfGHCi) $ do- loadFrameworks hsc_env platform pkg- -- See Note [Crash early load_dyn and locateLib]- -- Crash early if can't load any of `known_dlls`- mapM_ (load_dyn hsc_env True) known_dlls- -- For remaining `dlls` crash early only when there is surely- -- no package's DLL around ... (not is_dyn)- mapM_ (load_dyn hsc_env (not is_dyn) . platformSOName platform) dlls-#endif- -- After loading all the DLLs, we can load the static objects.- -- Ordering isn't important here, because we do one final link- -- step to resolve everything.- mapM_ (loadObj hsc_env) objs- mapM_ (loadArchive hsc_env) archs-- maybePutStr dflags "linking ... "- ok <- resolveObjs hsc_env-- -- DLLs are loaded, reset the search paths- -- Import libraries will be loaded via loadArchive so only- -- reset the DLL search path after all archives are loaded- -- as well.- mapM_ (removeLibrarySearchPath hsc_env) $ reverse pathCache-- if succeeded ok- then maybePutStrLn dflags "done."- else let errmsg = text "unable to load unit `"- <> pprUnitInfoForUser pkg <> text "'"- in throwGhcExceptionIO (InstallationError (showSDoc dflags errmsg))--{--Note [Crash early load_dyn and locateLib]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-If a package is "normal" (exposes it's code from more than zero Haskell-modules, unlike e.g. that in ghcilink004) and is built "dyn" way, then-it has it's code compiled and linked into the DLL, which GHCi linker picks-when loading the package's code (see the big comment in the beginning of-`locateLib`).--When loading DLLs, GHCi linker simply calls the system's `dlopen` or-`LoadLibrary` APIs. This is quite different from the case when GHCi linker-loads an object file or static library. When loading an object file or static-library GHCi linker parses them and resolves all symbols "manually".-These object file or static library may reference some external symbols-defined in some external DLLs. And GHCi should know which these-external DLLs are.--But when GHCi loads a DLL, it's the *system* linker who manages all-the necessary dependencies, and it is able to load this DLL not having-any extra info. Thus we don't *have to* crash in this case even if we-are unable to load any supposed dependencies explicitly.--Suppose during GHCi session a client of the package wants to-`foreign import` a symbol which isn't exposed by the package DLL, but-is exposed by such an external (dependency) DLL.-If the DLL isn't *explicitly* loaded because `load_dyn` failed to do-this, then the client code eventually crashes because the GHCi linker-isn't able to locate this symbol (GHCi linker maintains a list of-explicitly loaded DLLs it looks into when trying to find a symbol).--This is why we still should try to load all the dependency DLLs-even though we know that the system linker loads them implicitly when-loading the package DLL.--Why we still keep the `crash_early` opportunity then not allowing such-a permissive behaviour for any DLLs? Well, we, perhaps, improve a user-experience in some cases slightly.--But if it happens there exist other corner cases where our current-usage of `crash_early` flag is overly restrictive, we may lift the-restriction very easily.--}---- we have already searched the filesystem; the strings passed to load_dyn--- can be passed directly to loadDLL. They are either fully-qualified--- ("/usr/lib/libfoo.so"), or unqualified ("libfoo.so"). In the latter case,--- loadDLL is going to search the system paths to find the library.-load_dyn :: HscEnv -> Bool -> FilePath -> IO ()-load_dyn hsc_env crash_early dll = do- r <- loadDLL hsc_env dll- case r of- Nothing -> return ()- Just err ->- if crash_early- then cmdLineErrorIO err- else let dflags = hsc_dflags hsc_env in- when (wopt Opt_WarnMissedExtraSharedLib dflags)- $ putLogMsg dflags- (Reason Opt_WarnMissedExtraSharedLib) SevWarning- noSrcSpan $ withPprStyle defaultUserStyle (note err)- where- note err = vcat $ map text- [ err- , "It's OK if you don't want to use symbols from it directly."- , "(the package DLL is loaded by the system linker"- , " which manages dependencies by itself)." ]--loadFrameworks :: HscEnv -> Platform -> UnitInfo -> IO ()-loadFrameworks hsc_env platform pkg- = when (platformUsesFrameworks platform) $ mapM_ load frameworks- where- fw_dirs = map ST.unpack $ Packages.unitExtDepFrameworkDirs pkg- frameworks = map ST.unpack $ Packages.unitExtDepFrameworks pkg-- load fw = do r <- loadFramework hsc_env fw_dirs fw- case r of- Nothing -> return ()- Just err -> cmdLineErrorIO ("can't load framework: "- ++ fw ++ " (" ++ err ++ ")" )---- Try to find an object file for a given library in the given paths.--- If it isn't present, we assume that addDLL in the RTS can find it,--- which generally means that it should be a dynamic library in the--- standard system search path.--- For GHCi we tend to prefer dynamic libraries over static ones as--- they are easier to load and manage, have less overhead.-locateLib :: HscEnv -> Bool -> [FilePath] -> [FilePath] -> String- -> IO LibrarySpec-locateLib hsc_env is_hs lib_dirs gcc_dirs lib- | not is_hs- -- For non-Haskell libraries (e.g. gmp, iconv):- -- first look in library-dirs for a dynamic library (on User paths only)- -- (libfoo.so)- -- then try looking for import libraries on Windows (on User paths only)- -- (.dll.a, .lib)- -- first look in library-dirs for a dynamic library (on GCC paths only)- -- (libfoo.so)- -- then check for system dynamic libraries (e.g. kernel32.dll on windows)- -- then try looking for import libraries on Windows (on GCC paths only)- -- (.dll.a, .lib)- -- then look in library-dirs for a static library (libfoo.a)- -- then look in library-dirs and inplace GCC for a dynamic library (libfoo.so)- -- then try looking for import libraries on Windows (.dll.a, .lib)- -- then look in library-dirs and inplace GCC for a static library (libfoo.a)- -- then try "gcc --print-file-name" to search gcc's search path- -- for a dynamic library (#5289)- -- otherwise, assume loadDLL can find it- --- -- The logic is a bit complicated, but the rationale behind it is that- -- loading a shared library for us is O(1) while loading an archive is- -- O(n). Loading an import library is also O(n) so in general we prefer- -- shared libraries because they are simpler and faster.- --- =-#if defined(CAN_LOAD_DLL)- findDll user `orElse`-#endif- tryImpLib user `orElse`-#if defined(CAN_LOAD_DLL)- findDll gcc `orElse`- findSysDll `orElse`-#endif- tryImpLib gcc `orElse`- findArchive `orElse`- tryGcc `orElse`- assumeDll-- | loading_dynamic_hs_libs -- search for .so libraries first.- = findHSDll `orElse`- findDynObject `orElse`- assumeDll-- | otherwise- -- use HSfoo.{o,p_o} if it exists, otherwise fallback to libHSfoo{,_p}.a- = findObject `orElse`- findArchive `orElse`- assumeDll-- where- dflags = hsc_dflags hsc_env- interp = hscInterp hsc_env- dirs = lib_dirs ++ gcc_dirs- gcc = False- user = True-- obj_file- | is_hs && loading_profiled_hs_libs = lib <.> "p_o"- | otherwise = lib <.> "o"- dyn_obj_file = lib <.> "dyn_o"- arch_files = [ "lib" ++ lib ++ lib_tag <.> "a"- , lib <.> "a" -- native code has no lib_tag- , "lib" ++ lib, lib- ]- lib_tag = if is_hs && loading_profiled_hs_libs then "_p" else ""-- loading_profiled_hs_libs = interpreterProfiled interp- loading_dynamic_hs_libs = interpreterDynamic interp-- import_libs = [ lib <.> "lib" , "lib" ++ lib <.> "lib"- , "lib" ++ lib <.> "dll.a", lib <.> "dll.a"- ]-- hs_dyn_lib_name = lib ++ '-':programName dflags ++ projectVersion dflags- hs_dyn_lib_file = platformHsSOName platform hs_dyn_lib_name-- so_name = platformSOName platform lib- lib_so_name = "lib" ++ so_name- dyn_lib_file = case (arch, os) of- (ArchX86_64, OSSolaris2) -> "64" </> so_name- _ -> so_name-- findObject = liftM (fmap $ Objects . (:[])) $ findFile dirs obj_file- findDynObject = liftM (fmap $ Objects . (:[])) $ findFile dirs dyn_obj_file- findArchive = let local name = liftM (fmap Archive) $ findFile dirs name- in apply (map local arch_files)- findHSDll = liftM (fmap DLLPath) $ findFile dirs hs_dyn_lib_file- findDll re = let dirs' = if re == user then lib_dirs else gcc_dirs- in liftM (fmap DLLPath) $ findFile dirs' dyn_lib_file- findSysDll = fmap (fmap $ DLL . dropExtension . takeFileName) $- findSystemLibrary hsc_env so_name- tryGcc = let search = searchForLibUsingGcc dflags- dllpath = liftM (fmap DLLPath)- short = dllpath $ search so_name lib_dirs- full = dllpath $ search lib_so_name lib_dirs- gcc name = liftM (fmap Archive) $ search name lib_dirs- files = import_libs ++ arch_files- dlls = [short, full]- archives = map gcc files- in apply $-#if defined(CAN_LOAD_DLL)- dlls ++-#endif- archives- tryImpLib re = case os of- OSMinGW32 ->- let dirs' = if re == user then lib_dirs else gcc_dirs- implib name = liftM (fmap Archive) $- findFile dirs' name- in apply (map implib import_libs)- _ -> return Nothing-- -- TH Makes use of the interpreter so this failure is not obvious.- -- So we are nice and warn/inform users why we fail before we do.- -- But only for haskell libraries, as C libraries don't have a- -- profiling/non-profiling distinction to begin with.- assumeDll- | is_hs- , not loading_dynamic_hs_libs- , interpreterProfiled interp- = do- warningMsg dflags- (text "Interpreter failed to load profiled static library" <+> text lib <> char '.' $$- text " \tTrying dynamic library instead. If this fails try to rebuild" <+>- text "libraries with profiling support.")- return (DLL lib)- | otherwise = return (DLL lib)- infixr `orElse`- f `orElse` g = f >>= maybe g return-- apply :: [IO (Maybe a)] -> IO (Maybe a)- apply [] = return Nothing- apply (x:xs) = do x' <- x- if isJust x'- then return x'- else apply xs-- platform = targetPlatform dflags- arch = platformArch platform- os = platformOS platform--searchForLibUsingGcc :: DynFlags -> String -> [FilePath] -> IO (Maybe FilePath)-searchForLibUsingGcc dflags so dirs = do- -- GCC does not seem to extend the library search path (using -L) when using- -- --print-file-name. So instead pass it a new base location.- str <- askLd dflags (map (FileOption "-B") dirs- ++ [Option "--print-file-name", Option so])- let file = case lines str of- [] -> ""- l:_ -> l- if (file == so)- then return Nothing- else do b <- doesFileExist file -- file could be a folder (see #16063)- return (if b then Just file else Nothing)---- | Retrieve the list of search directory GCC and the System use to find--- libraries and components. See Note [Fork/Exec Windows].-getGCCPaths :: DynFlags -> OS -> IO [FilePath]-getGCCPaths dflags os- = case os of- OSMinGW32 ->- do gcc_dirs <- getGccSearchDirectory dflags "libraries"- sys_dirs <- getSystemDirectories- return $ nub $ gcc_dirs ++ sys_dirs- _ -> return []---- | Cache for the GCC search directories as this can't easily change--- during an invocation of GHC. (Maybe with some env. variable but we'll)--- deal with that highly unlikely scenario then.-{-# NOINLINE gccSearchDirCache #-}-gccSearchDirCache :: IORef [(String, [String])]-gccSearchDirCache = unsafePerformIO $ newIORef []---- Note [Fork/Exec Windows]--- ~~~~~~~~~~~~~~~~~~~~~~~~--- fork/exec is expensive on Windows, for each time we ask GCC for a library we--- have to eat the cost of af least 3 of these: gcc -> real_gcc -> cc1.--- So instead get a list of location that GCC would search and use findDirs--- which hopefully is written in an optimized mannor to take advantage of--- caching. At the very least we remove the overhead of the fork/exec and waits--- which dominate a large percentage of startup time on Windows.-getGccSearchDirectory :: DynFlags -> String -> IO [FilePath]-getGccSearchDirectory dflags key = do- cache <- readIORef gccSearchDirCache- case lookup key cache of- Just x -> return x- Nothing -> do- str <- askLd dflags [Option "--print-search-dirs"]- let line = dropWhile isSpace str- name = key ++ ": ="- if null line- then return []- else do let val = split $ find name line- dirs <- filterM doesDirectoryExist val- modifyIORef' gccSearchDirCache ((key, dirs):)- return val- where split :: FilePath -> [FilePath]- split r = case break (==';') r of- (s, [] ) -> [s]- (s, (_:xs)) -> s : split xs-- find :: String -> String -> String- find r x = let lst = lines x- val = filter (r `isPrefixOf`) lst- in if null val- then []- else case break (=='=') (head val) of- (_ , []) -> []- (_, (_:xs)) -> xs---- | Get a list of system search directories, this to alleviate pressure on--- the findSysDll function.-getSystemDirectories :: IO [FilePath]-#if defined(mingw32_HOST_OS)-getSystemDirectories = fmap (:[]) getSystemDirectory-#else-getSystemDirectories = return []-#endif---- | Merge the given list of paths with those in the environment variable--- given. If the variable does not exist then just return the identity.-addEnvPaths :: String -> [String] -> IO [String]-addEnvPaths name list- = do -- According to POSIX (chapter 8.3) a zero-length prefix means current- -- working directory. Replace empty strings in the env variable with- -- `working_dir` (see also #14695).- working_dir <- getCurrentDirectory- values <- lookupEnv name- case values of- Nothing -> return list- Just arr -> return $ list ++ splitEnv working_dir arr- where- splitEnv :: FilePath -> String -> [String]- splitEnv working_dir value =- case break (== envListSep) value of- (x, [] ) ->- [if null x then working_dir else x]- (x, (_:xs)) ->- (if null x then working_dir else x) : splitEnv working_dir xs-#if defined(mingw32_HOST_OS)- envListSep = ';'-#else- envListSep = ':'-#endif---- ------------------------------------------------------------------------------- Loading a dynamic library (dlopen()-ish on Unix, LoadLibrary-ish on Win32)--{--Note [macOS Big Sur dynamic libraries]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--macOS Big Sur makes the following change to how frameworks are shipped-with the OS:--> New in macOS Big Sur 11 beta, the system ships with a built-in-> dynamic linker cache of all system-provided libraries. As part of-> this change, copies of dynamic libraries are no longer present on-> the filesystem. Code that attempts to check for dynamic library-> presence by looking for a file at a path or enumerating a directory-> will fail. Instead, check for library presence by attempting to-> dlopen() the path, which will correctly check for the library in the-> cache. (62986286)--(https://developer.apple.com/documentation/macos-release-notes/macos-big-sur-11-beta-release-notes/)--Therefore, the previous method of checking whether a library exists-before attempting to load it makes GHC.Runtime.Linker.loadFramework-fail to find frameworks installed at /System/Library/Frameworks.-Instead, any attempt to load a framework at runtime, such as by-passing -framework OpenGL to runghc or running code loading such a-framework with GHCi, fails with a 'not found' message.--GHC.Runtime.Linker.loadFramework now opportunistically loads the-framework libraries without checking for their existence first,-failing only if all attempts to load a given framework from any of the-various possible locations fail. See also #18446, which this change-addresses.--}---- Darwin / MacOS X only: load a framework--- a framework is a dynamic library packaged inside a directory of the same--- name. They are searched for in different paths than normal libraries.-loadFramework :: HscEnv -> [FilePath] -> FilePath -> IO (Maybe String)-loadFramework hsc_env extraPaths rootname- = do { either_dir <- tryIO getHomeDirectory- ; let homeFrameworkPath = case either_dir of- Left _ -> []- Right dir -> [dir </> "Library/Frameworks"]- ps = extraPaths ++ homeFrameworkPath ++ defaultFrameworkPaths- ; errs <- findLoadDLL ps []- ; return $ fmap (intercalate ", ") errs- }- where- fwk_file = rootname <.> "framework" </> rootname-- -- sorry for the hardcoded paths, I hope they won't change anytime soon:- defaultFrameworkPaths = ["/Library/Frameworks", "/System/Library/Frameworks"]-- -- Try to call loadDLL for each candidate path.- --- -- See Note [macOS Big Sur dynamic libraries]- findLoadDLL [] errs =- -- Tried all our known library paths, but dlopen()- -- has no built-in paths for frameworks: give up- return $ Just errs- findLoadDLL (p:ps) errs =- do { dll <- loadDLL hsc_env (p </> fwk_file)- ; case dll of- Nothing -> return Nothing- Just err -> findLoadDLL ps ((p ++ ": " ++ err):errs)- }--{- **********************************************************************-- Helper functions-- ********************************************************************* -}--maybePutSDoc :: DynFlags -> SDoc -> IO ()-maybePutSDoc dflags s- = when (verbosity dflags > 1) $- putLogMsg dflags- NoReason- SevInteractive- noSrcSpan- $ withPprStyle defaultUserStyle s--maybePutStr :: DynFlags -> String -> IO ()-maybePutStr dflags s = maybePutSDoc dflags (text s)--maybePutStrLn :: DynFlags -> String -> IO ()-maybePutStrLn dflags s = maybePutStr dflags (s ++ "\n")
compiler/GHC/Runtime/Loader.hs view
@@ -27,7 +27,7 @@ import GHC.Driver.Hooks import GHC.Driver.Plugins -import GHC.Runtime.Linker ( linkModule, getHValue )+import GHC.Linker.Loader ( loadModule, loadName ) import GHC.Runtime.Interpreter ( wormhole, withInterp ) import GHC.Runtime.Interpreter.Types @@ -69,21 +69,22 @@ -- flags. Should be called after command line arguments are parsed, but before -- actual compilation starts. Idempotent operation. Should be re-called if -- pluginModNames or pluginModNameOpts changes.-initializePlugins :: HscEnv -> DynFlags -> IO DynFlags-initializePlugins hsc_env df- | map lpModuleName (cachedPlugins df)- == pluginModNames df -- plugins not changed- && all (\p -> paArguments (lpPlugin p)- == argumentsForPlugin p (pluginModNameOpts df))- (cachedPlugins df) -- arguments not changed- = return df -- no need to reload plugins+initializePlugins :: HscEnv -> IO HscEnv+initializePlugins hsc_env+ -- plugins not changed+ | map lpModuleName (hsc_plugins hsc_env) == pluginModNames dflags+ -- arguments not changed+ , all same_args (hsc_plugins hsc_env)+ = return hsc_env -- no need to reload plugins | otherwise- = do loadedPlugins <- loadPlugins (hsc_env { hsc_dflags = df })- let df' = df { cachedPlugins = loadedPlugins }- withPlugins df' runDflagsPlugin df'-- where argumentsForPlugin p = map snd . filter ((== lpModuleName p) . fst)- runDflagsPlugin p opts dynflags = dynflagsPlugin p opts dynflags+ = do loaded_plugins <- loadPlugins hsc_env+ let hsc_env' = hsc_env { hsc_plugins = loaded_plugins }+ withPlugins hsc_env' driverPlugin hsc_env'+ where+ plugin_args = pluginModNameOpts dflags+ same_args p = paArguments (lpPlugin p) == argumentsForPlugin p plugin_args+ argumentsForPlugin p = map snd . filter ((== lpModuleName p) . fst)+ dflags = hsc_dflags hsc_env loadPlugins :: HscEnv -> IO [LoadedPlugin] loadPlugins hsc_env@@ -209,11 +210,11 @@ then do -- Link in the module that contains the value, if it has such a module case nameModule_maybe val_name of- Just mod -> do linkModule hsc_env mod+ Just mod -> do loadModule hsc_env mod return () Nothing -> return () -- Find the value that we just linked in and cast it given that we have proved it's type- hval <- withInterp hsc_env $ \interp -> getHValue hsc_env val_name >>= wormhole interp+ hval <- withInterp hsc_env $ \interp -> loadName hsc_env val_name >>= wormhole interp return (Just hval) else return Nothing Just val_thing -> throwCmdLineErrorS dflags $ wrongTyThingError val_name val_thing
compiler/GHC/Stg/Lift/Analysis.hs view
@@ -95,7 +95,7 @@ -- -- * 'ClosureSk', representing closure allocation. -- * 'RhsSk', representing a RHS of a binding and how many times it's called--- by an appropriate 'DmdShell'.+-- by an appropriate 'Card'. -- * 'AltSk', 'BothSk' and 'NilSk' for choice, sequence and empty element. -- -- This abstraction is mostly so that the main analysis function 'closureGrowth'@@ -124,7 +124,7 @@ -- closures, multi-shot lambdas and case expressions. data Skeleton = ClosureSk !Id !DIdSet {- ^ free vars -} !Skeleton- | RhsSk !DmdShell {- ^ how often the RHS was entered -} !Skeleton+ | RhsSk !Card {- ^ how often the RHS was entered -} !Skeleton | AltSk !Skeleton !Skeleton | BothSk !Skeleton !Skeleton | NilSk@@ -139,7 +139,7 @@ altSk a NilSk = a altSk a b = AltSk a b -rhsSk :: DmdShell -> Skeleton -> Skeleton+rhsSk :: Card -> Skeleton -> Skeleton rhsSk _ NilSk = NilSk rhsSk body_dmd skel = RhsSk body_dmd skel @@ -172,22 +172,12 @@ ] ppr (BothSk l r) = ppr l $$ ppr r ppr (ClosureSk f fvs body) = ppr f <+> ppr fvs $$ nest 2 (ppr body)- ppr (RhsSk body_dmd body) = hcat- [ text "λ["- , ppr str- , text ", "- , ppr use- , text "]. "+ ppr (RhsSk card body) = hcat+ [ lambda+ , ppr card+ , dot , ppr body ]- where- str- | isStrictDmd body_dmd = '1'- | otherwise = '0'- use- | isAbsDmd body_dmd = '0'- | isUsedOnce body_dmd = '1'- | otherwise = 'ω' instance Outputable BinderInfo where ppr = ppr . binderInfoBndr@@ -333,19 +323,19 @@ where bndrs' = map BoringBinder bndrs (body_skel, body_arg_occs, body') = tagSkeletonExpr body- rhs_skel = rhsSk (rhsDmdShell bndr) body_skel+ rhs_skel = rhsSk (rhsCard bndr) body_skel -- | How many times will the lambda body of the RHS bound to the given -- identifier be evaluated, relative to its defining context? This function--- computes the answer in form of a 'DmdShell'.-rhsDmdShell :: Id -> DmdShell-rhsDmdShell bndr- | is_thunk = oneifyDmd ds+-- computes the answer in form of a 'Card'.+rhsCard :: Id -> Card+rhsCard bndr+ | is_thunk = oneifyCard n | otherwise = peelManyCalls (idArity bndr) cd where is_thunk = idArity bndr == 0 -- Let's pray idDemandInfo is still OK after unarise...- (ds, cd) = toCleanDmd (idDemandInfo bndr)+ n :* cd = idDemandInfo bndr tagSkeletonAlt :: CgStgAlt -> (Skeleton, IdSet, LlStgAlt) tagSkeletonAlt (con, bndrs, rhs)@@ -507,7 +497,7 @@ idClosureFootprint:: Platform -> Id -> WordOff idClosureFootprint platform = StgToCmm.ArgRep.argRepSizeW platform- . StgToCmm.ArgRep.idArgRep+ . StgToCmm.ArgRep.idArgRep platform -- | @closureGrowth expander sizer f fvs@ computes the closure growth in words -- as a result of lifting @f@ to top-level. If there was any growing closure@@ -550,7 +540,7 @@ -- Lifting @f@ removes @f@ from the closure but adds all @newbies@ cost = nonDetStrictFoldDVarSet (\id size -> sizer id + size) 0 newbies - n_occs -- Using a non-deterministic fold is OK here because addition is commutative.- go (RhsSk body_dmd body)+ go (RhsSk n body) -- The conservative assumption would be that -- 1. Every RHS with positive growth would be called multiple times, -- modulo thunks.@@ -561,11 +551,11 @@ -- considering information from the demand analyser, which provides us -- with conservative estimates on minimum and maximum evaluation -- cardinality. The @body_dmd@ part of 'RhsSk' is the result of- -- 'rhsDmdShell' and accurately captures the cardinality of the RHSs body+ -- 'rhsCard' and accurately captures the cardinality of the RHSs body -- relative to its defining context.- | isAbsDmd body_dmd = 0- | cg <= 0 = if isStrictDmd body_dmd then cg else 0- | isUsedOnce body_dmd = cg- | otherwise = infinity+ | isAbs n = 0+ | cg <= 0 = if isStrict n then cg else 0+ | isUsedOnce n = cg+ | otherwise = infinity where cg = go body
compiler/GHC/StgToCmm/ArgRep.hs view
@@ -65,28 +65,33 @@ argRepString V32 = "V32" argRepString V64 = "V64" -toArgRep :: PrimRep -> ArgRep-toArgRep VoidRep = V-toArgRep LiftedRep = P-toArgRep UnliftedRep = P-toArgRep IntRep = N-toArgRep WordRep = N-toArgRep Int8Rep = N -- Gets widened to native word width for calls-toArgRep Word8Rep = N -- Gets widened to native word width for calls-toArgRep Int16Rep = N -- Gets widened to native word width for calls-toArgRep Word16Rep = N -- Gets widened to native word width for calls-toArgRep Int32Rep = N -- Gets widened to native word width for calls-toArgRep Word32Rep = N -- Gets widened to native word width for calls-toArgRep AddrRep = N-toArgRep Int64Rep = L-toArgRep Word64Rep = L-toArgRep FloatRep = F-toArgRep DoubleRep = D-toArgRep (VecRep len elem) = case len*primElemRepSizeB elem of- 16 -> V16- 32 -> V32- 64 -> V64- _ -> error "toArgRep: bad vector primrep"+toArgRep :: Platform -> PrimRep -> ArgRep+toArgRep platform rep = case rep of+ VoidRep -> V+ LiftedRep -> P+ UnliftedRep -> P+ IntRep -> N+ WordRep -> N+ Int8Rep -> N -- Gets widened to native word width for calls+ Word8Rep -> N -- Gets widened to native word width for calls+ Int16Rep -> N -- Gets widened to native word width for calls+ Word16Rep -> N -- Gets widened to native word width for calls+ Int32Rep -> N -- Gets widened to native word width for calls+ Word32Rep -> N -- Gets widened to native word width for calls+ AddrRep -> N+ Int64Rep -> case platformWordSize platform of+ PW4 -> L+ PW8 -> N+ Word64Rep -> case platformWordSize platform of+ PW4 -> L+ PW8 -> N+ FloatRep -> F+ DoubleRep -> D+ (VecRep len elem) -> case len*primElemRepSizeB elem of+ 16 -> V16+ 32 -> V32+ 64 -> V64+ _ -> error "toArgRep: bad vector primrep" isNonV :: ArgRep -> Bool isNonV V = False@@ -106,8 +111,8 @@ where ws = platformWordSizeInBytes platform -idArgRep :: Id -> ArgRep-idArgRep = toArgRep . idPrimRep+idArgRep :: Platform -> Id -> ArgRep+idArgRep platform = toArgRep platform . idPrimRep -- This list of argument patterns should be kept in sync with at least -- the following:
compiler/GHC/StgToCmm/DataCon.hs view
@@ -102,6 +102,21 @@ nv_args_w_offsets) = mkVirtHeapOffsetsWithPadding profile StdHeader (addArgReps args) + ; let+ -- Decompose padding into units of length 8, 4, 2, or 1 bytes to+ -- allow the implementation of mk_payload to use widthFromBytes,+ -- which only handles these cases.+ fix_padding (x@(Padding n off) : rest)+ | n == 0 = fix_padding rest+ | n `elem` [1,2,4,8] = x : fix_padding rest+ | n > 8 = add_pad 8+ | n > 4 = add_pad 4+ | n > 2 = add_pad 2+ | otherwise = add_pad 1+ where add_pad m = Padding m off : fix_padding (Padding (n-m) (off+m) : rest)+ fix_padding (x : rest) = x : fix_padding rest+ fix_padding [] = []+ mk_payload (Padding len _) = return (CmmInt 0 (widthFromBytes len)) mk_payload (FieldOff arg _) = do amode <- getArgAmode arg@@ -117,7 +132,7 @@ info_tbl = mkDataConInfoTable profile con True ptr_wds nonptr_wds - ; payload <- mapM mk_payload nv_args_w_offsets+ ; payload <- mapM mk_payload (fix_padding nv_args_w_offsets) -- NB1: nv_args_w_offsets is sorted into ptrs then non-ptrs -- NB2: all the amodes should be Lits! -- TODO (osa): Why?
compiler/GHC/StgToCmm/Layout.hs view
@@ -321,12 +321,14 @@ -- using zeroCLit or even undefined would work, but would be ugly). -- getArgRepsAmodes :: [StgArg] -> FCode [(ArgRep, Maybe CmmExpr)]-getArgRepsAmodes = mapM getArgRepAmode- where getArgRepAmode arg+getArgRepsAmodes args = do+ platform <- profilePlatform <$> getProfile+ mapM (getArgRepAmode platform) args+ where getArgRepAmode platform arg | V <- rep = return (V, Nothing) | otherwise = do expr <- getArgAmode (NonVoid arg) return (rep, Just expr)- where rep = toArgRep (argPrimRep arg)+ where rep = toArgRep platform (argPrimRep arg) nonVArgs :: [(ArgRep, Maybe CmmExpr)] -> [CmmExpr] nonVArgs [] = []@@ -542,7 +544,7 @@ mkArgDescr :: Platform -> [Id] -> ArgDescr mkArgDescr platform args = let arg_bits = argBits platform arg_reps- arg_reps = filter isNonV (map idArgRep args)+ arg_reps = filter isNonV (map (idArgRep platform) args) -- Getting rid of voids eases matching of standard patterns in case stdPattern arg_reps of Just spec_id -> ArgSpec spec_id
compiler/GHC/StgToCmm/Prim.hs view
@@ -848,11 +848,30 @@ -- Atomic operations InterlockedExchange_Addr -> \[src, value] -> opIntoRegs $ \[res] -> emitPrimCall [res] (MO_Xchg (wordWidth platform)) [src, value]- InterlockedExchange_Int -> \[src, value] -> opIntoRegs $ \[res] ->+ InterlockedExchange_Word -> \[src, value] -> opIntoRegs $ \[res] -> emitPrimCall [res] (MO_Xchg (wordWidth platform)) [src, value]- AtomicCompareExchange_Int -> \[dst, expected, new] -> opIntoRegs $ \[res] ->++ FetchAddAddrOp_Word -> \[addr, n] -> opIntoRegs $ \[res] ->+ doAtomicAddrRMW res AMO_Add addr (bWord platform) n+ FetchSubAddrOp_Word -> \[addr, n] -> opIntoRegs $ \[res] ->+ doAtomicAddrRMW res AMO_Sub addr (bWord platform) n+ FetchAndAddrOp_Word -> \[addr, n] -> opIntoRegs $ \[res] ->+ doAtomicAddrRMW res AMO_And addr (bWord platform) n+ FetchNandAddrOp_Word -> \[addr, n] -> opIntoRegs $ \[res] ->+ doAtomicAddrRMW res AMO_Nand addr (bWord platform) n+ FetchOrAddrOp_Word -> \[addr, n] -> opIntoRegs $ \[res] ->+ doAtomicAddrRMW res AMO_Or addr (bWord platform) n+ FetchXorAddrOp_Word -> \[addr, n] -> opIntoRegs $ \[res] ->+ doAtomicAddrRMW res AMO_Xor addr (bWord platform) n++ AtomicReadAddrOp_Word -> \[addr] -> opIntoRegs $ \[res] ->+ doAtomicReadAddr res addr (bWord platform)+ AtomicWriteAddrOp_Word -> \[addr, val] -> opIntoRegs $ \[] ->+ doAtomicWriteAddr addr (bWord platform) val++ CasAddrOp_Addr -> \[dst, expected, new] -> opIntoRegs $ \[res] -> emitPrimCall [res] (MO_Cmpxchg (wordWidth platform)) [dst, expected, new]- AtomicCompareExchange_Addr -> \[dst, expected, new] -> opIntoRegs $ \[res] ->+ CasAddrOp_Word -> \[dst, expected, new] -> opIntoRegs $ \[res] -> emitPrimCall [res] (MO_Cmpxchg (wordWidth platform)) [dst, expected, new] -- SIMD primops@@ -1040,17 +1059,17 @@ -- Atomic read-modify-write FetchAddByteArrayOp_Int -> \[mba, ix, n] -> opIntoRegs $ \[res] ->- doAtomicRMW res AMO_Add mba ix (bWord platform) n+ doAtomicByteArrayRMW res AMO_Add mba ix (bWord platform) n FetchSubByteArrayOp_Int -> \[mba, ix, n] -> opIntoRegs $ \[res] ->- doAtomicRMW res AMO_Sub mba ix (bWord platform) n+ doAtomicByteArrayRMW res AMO_Sub mba ix (bWord platform) n FetchAndByteArrayOp_Int -> \[mba, ix, n] -> opIntoRegs $ \[res] ->- doAtomicRMW res AMO_And mba ix (bWord platform) n+ doAtomicByteArrayRMW res AMO_And mba ix (bWord platform) n FetchNandByteArrayOp_Int -> \[mba, ix, n] -> opIntoRegs $ \[res] ->- doAtomicRMW res AMO_Nand mba ix (bWord platform) n+ doAtomicByteArrayRMW res AMO_Nand mba ix (bWord platform) n FetchOrByteArrayOp_Int -> \[mba, ix, n] -> opIntoRegs $ \[res] ->- doAtomicRMW res AMO_Or mba ix (bWord platform) n+ doAtomicByteArrayRMW res AMO_Or mba ix (bWord platform) n FetchXorByteArrayOp_Int -> \[mba, ix, n] -> opIntoRegs $ \[res] ->- doAtomicRMW res AMO_Xor mba ix (bWord platform) n+ doAtomicByteArrayRMW res AMO_Xor mba ix (bWord platform) n AtomicReadByteArrayOp_Int -> \[mba, ix] -> opIntoRegs $ \[res] -> doAtomicReadByteArray res mba ix (bWord platform) AtomicWriteByteArrayOp_Int -> \[mba, ix, val] -> opIntoRegs $ \[] ->@@ -1128,12 +1147,12 @@ AddrEqOp -> \args -> opTranslate args (mo_wordEq platform) AddrNeOp -> \args -> opTranslate args (mo_wordNe platform) - AndOp -> \args -> opTranslate args (mo_wordAnd platform)- OrOp -> \args -> opTranslate args (mo_wordOr platform)- XorOp -> \args -> opTranslate args (mo_wordXor platform)- NotOp -> \args -> opTranslate args (mo_wordNot platform)- SllOp -> \args -> opTranslate args (mo_wordShl platform)- SrlOp -> \args -> opTranslate args (mo_wordUShr platform)+ WordAndOp -> \args -> opTranslate args (mo_wordAnd platform)+ WordOrOp -> \args -> opTranslate args (mo_wordOr platform)+ WordXorOp -> \args -> opTranslate args (mo_wordXor platform)+ WordNotOp -> \args -> opTranslate args (mo_wordNot platform)+ WordSllOp -> \args -> opTranslate args (mo_wordShl platform)+ WordSrlOp -> \args -> opTranslate args (mo_wordUShr platform) AddrRemOp -> \args -> opTranslate args (mo_wordURem platform) @@ -1150,13 +1169,13 @@ IntGtOp -> \args -> opTranslate args (mo_wordSGt platform) IntLtOp -> \args -> opTranslate args (mo_wordSLt platform) - AndIOp -> \args -> opTranslate args (mo_wordAnd platform)- OrIOp -> \args -> opTranslate args (mo_wordOr platform)- XorIOp -> \args -> opTranslate args (mo_wordXor platform)- NotIOp -> \args -> opTranslate args (mo_wordNot platform)- ISllOp -> \args -> opTranslate args (mo_wordShl platform)- ISraOp -> \args -> opTranslate args (mo_wordSShr platform)- ISrlOp -> \args -> opTranslate args (mo_wordUShr platform)+ IntAndOp -> \args -> opTranslate args (mo_wordAnd platform)+ IntOrOp -> \args -> opTranslate args (mo_wordOr platform)+ IntXorOp -> \args -> opTranslate args (mo_wordXor platform)+ IntNotOp -> \args -> opTranslate args (mo_wordNot platform)+ IntSllOp -> \args -> opTranslate args (mo_wordShl platform)+ IntSraOp -> \args -> opTranslate args (mo_wordSShr platform)+ IntSrlOp -> \args -> opTranslate args (mo_wordUShr platform) -- Native word unsigned ops @@ -1176,8 +1195,8 @@ -- Int8# signed ops - Int8Extend -> \args -> opTranslate args (MO_SS_Conv W8 (wordWidth platform))- Int8Narrow -> \args -> opTranslate args (MO_SS_Conv (wordWidth platform) W8)+ Int8ExtendOp -> \args -> opTranslate args (MO_SS_Conv W8 (wordWidth platform))+ Int8NarrowOp -> \args -> opTranslate args (MO_SS_Conv (wordWidth platform) W8) Int8NegOp -> \args -> opTranslate args (MO_S_Neg W8) Int8AddOp -> \args -> opTranslate args (MO_Add W8) Int8SubOp -> \args -> opTranslate args (MO_Sub W8)@@ -1194,58 +1213,68 @@ -- Word8# unsigned ops - Word8Extend -> \args -> opTranslate args (MO_UU_Conv W8 (wordWidth platform))- Word8Narrow -> \args -> opTranslate args (MO_UU_Conv (wordWidth platform) W8)- Word8NotOp -> \args -> opTranslate args (MO_Not W8)- Word8AddOp -> \args -> opTranslate args (MO_Add W8)- Word8SubOp -> \args -> opTranslate args (MO_Sub W8)- Word8MulOp -> \args -> opTranslate args (MO_Mul W8)- Word8QuotOp -> \args -> opTranslate args (MO_U_Quot W8)- Word8RemOp -> \args -> opTranslate args (MO_U_Rem W8)+ Word8ExtendOp -> \args -> opTranslate args (MO_UU_Conv W8 (wordWidth platform))+ Word8NarrowOp -> \args -> opTranslate args (MO_UU_Conv (wordWidth platform) W8)+ Word8NotOp -> \args -> opTranslate args (MO_Not W8)+ Word8AddOp -> \args -> opTranslate args (MO_Add W8)+ Word8SubOp -> \args -> opTranslate args (MO_Sub W8)+ Word8MulOp -> \args -> opTranslate args (MO_Mul W8)+ Word8QuotOp -> \args -> opTranslate args (MO_U_Quot W8)+ Word8RemOp -> \args -> opTranslate args (MO_U_Rem W8) - Word8EqOp -> \args -> opTranslate args (MO_Eq W8)- Word8GeOp -> \args -> opTranslate args (MO_U_Ge W8)- Word8GtOp -> \args -> opTranslate args (MO_U_Gt W8)- Word8LeOp -> \args -> opTranslate args (MO_U_Le W8)- Word8LtOp -> \args -> opTranslate args (MO_U_Lt W8)- Word8NeOp -> \args -> opTranslate args (MO_Ne W8)+ Word8EqOp -> \args -> opTranslate args (MO_Eq W8)+ Word8GeOp -> \args -> opTranslate args (MO_U_Ge W8)+ Word8GtOp -> \args -> opTranslate args (MO_U_Gt W8)+ Word8LeOp -> \args -> opTranslate args (MO_U_Le W8)+ Word8LtOp -> \args -> opTranslate args (MO_U_Lt W8)+ Word8NeOp -> \args -> opTranslate args (MO_Ne W8) -- Int16# signed ops - Int16Extend -> \args -> opTranslate args (MO_SS_Conv W16 (wordWidth platform))- Int16Narrow -> \args -> opTranslate args (MO_SS_Conv (wordWidth platform) W16)- Int16NegOp -> \args -> opTranslate args (MO_S_Neg W16)- Int16AddOp -> \args -> opTranslate args (MO_Add W16)- Int16SubOp -> \args -> opTranslate args (MO_Sub W16)- Int16MulOp -> \args -> opTranslate args (MO_Mul W16)- Int16QuotOp -> \args -> opTranslate args (MO_S_Quot W16)- Int16RemOp -> \args -> opTranslate args (MO_S_Rem W16)+ Int16ExtendOp -> \args -> opTranslate args (MO_SS_Conv W16 (wordWidth platform))+ Int16NarrowOp -> \args -> opTranslate args (MO_SS_Conv (wordWidth platform) W16)+ Int16NegOp -> \args -> opTranslate args (MO_S_Neg W16)+ Int16AddOp -> \args -> opTranslate args (MO_Add W16)+ Int16SubOp -> \args -> opTranslate args (MO_Sub W16)+ Int16MulOp -> \args -> opTranslate args (MO_Mul W16)+ Int16QuotOp -> \args -> opTranslate args (MO_S_Quot W16)+ Int16RemOp -> \args -> opTranslate args (MO_S_Rem W16) - Int16EqOp -> \args -> opTranslate args (MO_Eq W16)- Int16GeOp -> \args -> opTranslate args (MO_S_Ge W16)- Int16GtOp -> \args -> opTranslate args (MO_S_Gt W16)- Int16LeOp -> \args -> opTranslate args (MO_S_Le W16)- Int16LtOp -> \args -> opTranslate args (MO_S_Lt W16)- Int16NeOp -> \args -> opTranslate args (MO_Ne W16)+ Int16EqOp -> \args -> opTranslate args (MO_Eq W16)+ Int16GeOp -> \args -> opTranslate args (MO_S_Ge W16)+ Int16GtOp -> \args -> opTranslate args (MO_S_Gt W16)+ Int16LeOp -> \args -> opTranslate args (MO_S_Le W16)+ Int16LtOp -> \args -> opTranslate args (MO_S_Lt W16)+ Int16NeOp -> \args -> opTranslate args (MO_Ne W16) -- Word16# unsigned ops - Word16Extend -> \args -> opTranslate args (MO_UU_Conv W16 (wordWidth platform))- Word16Narrow -> \args -> opTranslate args (MO_UU_Conv (wordWidth platform) W16)- Word16NotOp -> \args -> opTranslate args (MO_Not W16)- Word16AddOp -> \args -> opTranslate args (MO_Add W16)- Word16SubOp -> \args -> opTranslate args (MO_Sub W16)- Word16MulOp -> \args -> opTranslate args (MO_Mul W16)- Word16QuotOp -> \args -> opTranslate args (MO_U_Quot W16)- Word16RemOp -> \args -> opTranslate args (MO_U_Rem W16)+ Word16ExtendOp -> \args -> opTranslate args (MO_UU_Conv W16 (wordWidth platform))+ Word16NarrowOp -> \args -> opTranslate args (MO_UU_Conv (wordWidth platform) W16)+ Word16NotOp -> \args -> opTranslate args (MO_Not W16)+ Word16AddOp -> \args -> opTranslate args (MO_Add W16)+ Word16SubOp -> \args -> opTranslate args (MO_Sub W16)+ Word16MulOp -> \args -> opTranslate args (MO_Mul W16)+ Word16QuotOp -> \args -> opTranslate args (MO_U_Quot W16)+ Word16RemOp -> \args -> opTranslate args (MO_U_Rem W16) - Word16EqOp -> \args -> opTranslate args (MO_Eq W16)- Word16GeOp -> \args -> opTranslate args (MO_U_Ge W16)- Word16GtOp -> \args -> opTranslate args (MO_U_Gt W16)- Word16LeOp -> \args -> opTranslate args (MO_U_Le W16)- Word16LtOp -> \args -> opTranslate args (MO_U_Lt W16)- Word16NeOp -> \args -> opTranslate args (MO_Ne W16)+ Word16EqOp -> \args -> opTranslate args (MO_Eq W16)+ Word16GeOp -> \args -> opTranslate args (MO_U_Ge W16)+ Word16GtOp -> \args -> opTranslate args (MO_U_Gt W16)+ Word16LeOp -> \args -> opTranslate args (MO_U_Le W16)+ Word16LtOp -> \args -> opTranslate args (MO_U_Lt W16)+ Word16NeOp -> \args -> opTranslate args (MO_Ne W16) +-- Int32# signed ops++ Int32ExtendOp -> \args -> opTranslate args (MO_SS_Conv W32 (wordWidth platform))+ Int32NarrowOp -> \args -> opTranslate args (MO_SS_Conv (wordWidth platform) W32)++-- Word32# unsigned ops++ Word32ExtendOp -> \args -> opTranslate args (MO_UU_Conv W32 (wordWidth platform))+ Word32NarrowOp -> \args -> opTranslate args (MO_UU_Conv (wordWidth platform) W32)+ -- Char# ops CharEqOp -> \args -> opTranslate args (MO_Eq (wordWidth platform))@@ -2855,22 +2884,33 @@ -- | Emit an atomic modification to a byte array element. The result -- reg contains that previous value of the element. Implies a full -- memory barrier.-doAtomicRMW :: LocalReg -- ^ Result reg+doAtomicByteArrayRMW+ :: LocalReg -- ^ Result reg -> AtomicMachOp -- ^ Atomic op (e.g. add) -> CmmExpr -- ^ MutableByteArray# -> CmmExpr -- ^ Index -> CmmType -- ^ Type of element by which we are indexing -> CmmExpr -- ^ Op argument (e.g. amount to add) -> FCode ()-doAtomicRMW res amop mba idx idx_ty n = do+doAtomicByteArrayRMW res amop mba idx idx_ty n = do profile <- getProfile platform <- getPlatform let width = typeWidth idx_ty addr = cmmIndexOffExpr platform (arrWordsHdrSize profile) width mba idx+ doAtomicAddrRMW res amop addr idx_ty n++doAtomicAddrRMW+ :: LocalReg -- ^ Result reg+ -> AtomicMachOp -- ^ Atomic op (e.g. add)+ -> CmmExpr -- ^ Addr#+ -> CmmType -- ^ Pointed value type+ -> CmmExpr -- ^ Op argument (e.g. amount to add)+ -> FCode ()+doAtomicAddrRMW res amop addr ty n = do emitPrimCall [ res ]- (MO_AtomicRMW width amop)+ (MO_AtomicRMW (typeWidth ty) amop) [ addr, n ] -- | Emit an atomic read to a byte array that acts as a memory barrier.@@ -2886,9 +2926,18 @@ let width = typeWidth idx_ty addr = cmmIndexOffExpr platform (arrWordsHdrSize profile) width mba idx+ doAtomicReadAddr res addr idx_ty++-- | Emit an atomic read to an address that acts as a memory barrier.+doAtomicReadAddr+ :: LocalReg -- ^ Result reg+ -> CmmExpr -- ^ Addr#+ -> CmmType -- ^ Type of element by which we are indexing+ -> FCode ()+doAtomicReadAddr res addr ty = do emitPrimCall [ res ]- (MO_AtomicRead width)+ (MO_AtomicRead (typeWidth ty)) [ addr ] -- | Emit an atomic write to a byte array that acts as a memory barrier.@@ -2904,9 +2953,18 @@ let width = typeWidth idx_ty addr = cmmIndexOffExpr platform (arrWordsHdrSize profile) width mba idx+ doAtomicWriteAddr addr idx_ty val++-- | Emit an atomic write to an address that acts as a memory barrier.+doAtomicWriteAddr+ :: CmmExpr -- ^ Addr#+ -> CmmType -- ^ Type of element by which we are indexing+ -> CmmExpr -- ^ Value to write+ -> FCode ()+doAtomicWriteAddr addr ty val = do emitPrimCall [ {- no results -} ]- (MO_AtomicWrite width)+ (MO_AtomicWrite (typeWidth ty)) [ addr, val ] doCasByteArray
compiler/GHC/StgToCmm/Ticky.hs view
@@ -409,10 +409,11 @@ tickySlowCallPat (map argPrimRep args) tickySlowCallPat :: [PrimRep] -> FCode ()-tickySlowCallPat args = ifTicky $- let argReps = map toArgRep args+tickySlowCallPat args = ifTicky $ do+ platform <- profilePlatform <$> getProfile+ let argReps = map (toArgRep platform) args (_, n_matched) = slowCallPattern argReps- in if n_matched > 0 && args `lengthIs` n_matched+ if n_matched > 0 && args `lengthIs` n_matched then bumpTickyLbl $ mkRtsSlowFastTickyCtrLabel $ concatMap (map Data.Char.toLower . argRepString) argReps else bumpTickyCounter $ fsLit "VERY_SLOW_CALL_ctr"
compiler/GHC/StgToCmm/Utils.hs view
@@ -106,8 +106,14 @@ (wordWidth platform) LitNullAddr -> zeroCLit platform (LitNumber LitNumInt i) -> CmmInt i (wordWidth platform)+ (LitNumber LitNumInt8 i) -> CmmInt i W8+ (LitNumber LitNumInt16 i) -> CmmInt i W16+ (LitNumber LitNumInt32 i) -> CmmInt i W32 (LitNumber LitNumInt64 i) -> CmmInt i W64 (LitNumber LitNumWord i) -> CmmInt i (wordWidth platform)+ (LitNumber LitNumWord8 i) -> CmmInt i W8+ (LitNumber LitNumWord16 i) -> CmmInt i W16+ (LitNumber LitNumWord32 i) -> CmmInt i W32 (LitNumber LitNumWord64 i) -> CmmInt i W64 (LitFloat r) -> CmmFloat r W32 (LitDouble r) -> CmmFloat r W64
compiler/GHC/SysTools.hs view
@@ -20,21 +20,12 @@ module GHC.SysTools.Tasks, module GHC.SysTools.Info, - linkDynLib,- copy, copyWithHeader, -- * General utilities Option(..), expandTopDir,-- -- * Platform-specifics- libmLinkOpts,-- -- * Mac OS X frameworks- getUnitFrameworkOpts,- getFrameworkOpts ) where #include "GhclibHsVersions.h"@@ -43,25 +34,19 @@ import GHC.Settings.Utils -import GHC.Unit-import GHC.Unit.State import GHC.Utils.Error import GHC.Utils.Panic-import GHC.Utils.Outputable-import GHC.Platform import GHC.Driver.Session-import GHC.Platform.Ways import Control.Monad.Trans.Except (runExceptT) import System.FilePath import System.IO import System.IO.Unsafe (unsafeInterleaveIO)-import GHC.SysTools.ExtraObj+import GHC.Linker.ExtraObj import GHC.SysTools.Info import GHC.SysTools.Tasks import GHC.SysTools.BaseDir import GHC.Settings.IO-import qualified Data.Set as Set {- Note [How GHC finds toolchain utilities]@@ -223,284 +208,3 @@ hSetEncoding h utf8 hPutStr h str hSetBinaryMode h True--{--************************************************************************-* *-\subsection{Support code}-* *-************************************************************************--}--linkDynLib :: DynFlags -> [String] -> [UnitId] -> IO ()-linkDynLib dflags0 o_files dep_packages- = do- let platform = targetPlatform dflags0- os = platformOS platform-- -- This is a rather ugly hack to fix dynamically linked- -- GHC on Windows. If GHC is linked with -threaded, then- -- it links against libHSrts_thr. But if base is linked- -- against libHSrts, then both end up getting loaded,- -- and things go wrong. We therefore link the libraries- -- with the same RTS flags that we link GHC with.- dflags | OSMinGW32 <- os- , hostWays `hasWay` WayDyn- = dflags0 { ways = hostWays }- | otherwise- = dflags0-- verbFlags = getVerbFlags dflags- o_file = outputFile dflags-- pkgs_with_rts <- getPreloadUnitsAnd- (initSDocContext dflags defaultUserStyle)- (unitState dflags)- (mkHomeUnitFromFlags dflags)- dep_packages-- let pkg_lib_paths = collectLibraryPaths (ways dflags) pkgs_with_rts- let pkg_lib_path_opts = concatMap get_pkg_lib_path_opts pkg_lib_paths- get_pkg_lib_path_opts l- | ( osElfTarget (platformOS (targetPlatform dflags)) ||- osMachOTarget (platformOS (targetPlatform dflags)) ) &&- dynLibLoader dflags == SystemDependent &&- -- Only if we want dynamic libraries- WayDyn `Set.member` ways dflags &&- -- Only use RPath if we explicitly asked for it- gopt Opt_RPath dflags- = ["-L" ++ l, "-Xlinker", "-rpath", "-Xlinker", l]- -- See Note [-Xlinker -rpath vs -Wl,-rpath]- | otherwise = ["-L" ++ l]-- let lib_paths = libraryPaths dflags- let lib_path_opts = map ("-L"++) lib_paths-- -- In general we don't want to link our dynamic libs against the RTS- -- package, because the RTS lib comes in several flavours and we want to be- -- able to pick the flavour when a binary is linked.- --- -- But:- -- * on Windows we need to link the RTS import lib as Windows does not- -- allow undefined symbols.- --- -- * the RTS library path is still added to the library search path above- -- in case the RTS is being explicitly linked in (see #3807).- --- -- * if -flink-rts is used, we link with the rts.- --- let pkgs_without_rts = filter ((/= rtsUnitId) . unitId) pkgs_with_rts- pkgs- | OSMinGW32 <- os = pkgs_with_rts- | gopt Opt_LinkRts dflags = pkgs_with_rts- | otherwise = pkgs_without_rts- pkg_link_opts = package_hs_libs ++ extra_libs ++ other_flags- where (package_hs_libs, extra_libs, other_flags) = collectLinkOpts dflags pkgs-- -- probably _stub.o files- -- and last temporary shared object file- let extra_ld_inputs = ldInputs dflags-- -- frameworks- pkg_framework_opts <- getUnitFrameworkOpts dflags platform- (map unitId pkgs)- let framework_opts = getFrameworkOpts dflags platform-- case os of- OSMinGW32 -> do- -------------------------------------------------------------- -- Making a DLL- -------------------------------------------------------------- let output_fn = case o_file of- Just s -> s- Nothing -> "HSdll.dll"-- runLink dflags (- map Option verbFlags- ++ [ Option "-o"- , FileOption "" output_fn- , Option "-shared"- ] ++- [ FileOption "-Wl,--out-implib=" (output_fn ++ ".a")- | gopt Opt_SharedImplib dflags- ]- ++ map (FileOption "") o_files-- -- Permit the linker to auto link _symbol to _imp_symbol- -- This lets us link against DLLs without needing an "import library"- ++ [Option "-Wl,--enable-auto-import"]-- ++ extra_ld_inputs- ++ map Option (- lib_path_opts- ++ pkg_lib_path_opts- ++ pkg_link_opts- ))- _ | os == OSDarwin -> do- -------------------------------------------------------------------- -- Making a darwin dylib- -------------------------------------------------------------------- -- About the options used for Darwin:- -- -dynamiclib- -- Apple's way of saying -shared- -- -undefined dynamic_lookup:- -- Without these options, we'd have to specify the correct- -- dependencies for each of the dylibs. Note that we could- -- (and should) do without this for all libraries except- -- the RTS; all we need to do is to pass the correct- -- HSfoo_dyn.dylib files to the link command.- -- This feature requires Mac OS X 10.3 or later; there is- -- a similar feature, -flat_namespace -undefined suppress,- -- which works on earlier versions, but it has other- -- disadvantages.- -- -single_module- -- Build the dynamic library as a single "module", i.e. no- -- dynamic binding nonsense when referring to symbols from- -- within the library. The NCG assumes that this option is- -- specified (on i386, at least).- -- -install_name- -- Mac OS/X stores the path where a dynamic library is (to- -- be) installed in the library itself. It's called the- -- "install name" of the library. Then any library or- -- executable that links against it before it's installed- -- will search for it in its ultimate install location.- -- By default we set the install name to the absolute path- -- at build time, but it can be overridden by the- -- -dylib-install-name option passed to ghc. Cabal does- -- this.- --------------------------------------------------------------------- let output_fn = case o_file of { Just s -> s; Nothing -> "a.out"; }-- instName <- case dylibInstallName dflags of- Just n -> return n- Nothing -> return $ "@rpath" `combine` (takeFileName output_fn)- runLink dflags (- map Option verbFlags- ++ [ Option "-dynamiclib"- , Option "-o"- , FileOption "" output_fn- ]- ++ map Option o_files- ++ [ Option "-undefined",- Option "dynamic_lookup",- Option "-single_module" ]- ++ (if platformArch platform == ArchX86_64- then [ ]- else [ Option "-Wl,-read_only_relocs,suppress" ])- ++ [ Option "-install_name", Option instName ]- ++ map Option lib_path_opts- ++ extra_ld_inputs- ++ map Option framework_opts- ++ map Option pkg_lib_path_opts- ++ map Option pkg_link_opts- ++ map Option pkg_framework_opts- -- dead_strip_dylibs, will remove unused dylibs, and thus save- -- space in the load commands. The -headerpad is necessary so- -- that we can inject more @rpath's later for the leftover- -- libraries in the runInjectRpaths phase below.- --- -- See Note [Dynamic linking on macOS]- ++ [ Option "-Wl,-dead_strip_dylibs", Option "-Wl,-headerpad,8000" ]- )- runInjectRPaths dflags pkg_lib_paths output_fn- _ -> do- -------------------------------------------------------------------- -- Making a DSO- --------------------------------------------------------------------- let output_fn = case o_file of { Just s -> s; Nothing -> "a.out"; }- unregisterised = platformUnregisterised (targetPlatform dflags)- let bsymbolicFlag = -- we need symbolic linking to resolve- -- non-PIC intra-package-relocations for- -- performance (where symbolic linking works)- -- See Note [-Bsymbolic assumptions by GHC]- ["-Wl,-Bsymbolic" | not unregisterised]-- runLink dflags (- map Option verbFlags- ++ libmLinkOpts- ++ [ Option "-o"- , FileOption "" output_fn- ]- ++ map Option o_files- ++ [ Option "-shared" ]- ++ map Option bsymbolicFlag- -- Set the library soname. We use -h rather than -soname as- -- Solaris 10 doesn't support the latter:- ++ [ Option ("-Wl,-h," ++ takeFileName output_fn) ]- ++ extra_ld_inputs- ++ map Option lib_path_opts- ++ map Option pkg_lib_path_opts- ++ map Option pkg_link_opts- )---- | Some platforms require that we explicitly link against @libm@ if any--- math-y things are used (which we assume to include all programs). See #14022.-libmLinkOpts :: [Option]-libmLinkOpts =-#if defined(HAVE_LIBM)- [Option "-lm"]-#else- []-#endif--getUnitFrameworkOpts :: DynFlags -> Platform -> [UnitId] -> IO [String]-getUnitFrameworkOpts dflags platform dep_packages- | platformUsesFrameworks platform = do- pkg_framework_path_opts <- do- pkg_framework_paths <- getUnitFrameworkPath- (initSDocContext dflags defaultUserStyle)- (unitState dflags)- (mkHomeUnitFromFlags dflags)- dep_packages- return $ map ("-F" ++) pkg_framework_paths-- pkg_framework_opts <- do- pkg_frameworks <- getUnitFrameworks- (initSDocContext dflags defaultUserStyle)- (unitState dflags)- (mkHomeUnitFromFlags dflags)- dep_packages- return $ concat [ ["-framework", fw] | fw <- pkg_frameworks ]-- return (pkg_framework_path_opts ++ pkg_framework_opts)-- | otherwise = return []--getFrameworkOpts :: DynFlags -> Platform -> [String]-getFrameworkOpts dflags platform- | platformUsesFrameworks platform = framework_path_opts ++ framework_opts- | otherwise = []- where- framework_paths = frameworkPaths dflags- framework_path_opts = map ("-F" ++) framework_paths-- frameworks = cmdlineFrameworks dflags- -- reverse because they're added in reverse order from the cmd line:- framework_opts = concat [ ["-framework", fw]- | fw <- reverse frameworks ]--{--Note [-Bsymbolic assumptions by GHC]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--GHC has a few assumptions about interaction of relocations in NCG and linker:--1. -Bsymbolic resolves internal references when the shared library is linked,- which is important for performance.-2. When there is a reference to data in a shared library from the main program,- the runtime linker relocates the data object into the main program using an- R_*_COPY relocation.-3. If we used -Bsymbolic, then this results in multiple copies of the data- object, because some references have already been resolved to point to the- original instance. This is bad!--We work around [3.] for native compiled code by avoiding the generation of-R_*_COPY relocations.--Unregisterised compiler can't evade R_*_COPY relocations easily thus we disable--Bsymbolic linking there.--See related tickets: #4210, #15338--}
− compiler/GHC/SysTools/ExtraObj.hs
@@ -1,251 +0,0 @@------------------------------------------------------------------------------------ GHC Extra object linking code------ (c) The GHC Team 2017-----------------------------------------------------------------------------------module GHC.SysTools.ExtraObj (- mkExtraObj, mkExtraObjToLinkIntoBinary, mkNoteObjsToLinkIntoBinary,- checkLinkInfo, getLinkInfo, getCompilerInfo,- ghcLinkInfoSectionName, ghcLinkInfoNoteName, platformSupportsSavingLinkOpts,- haveRtsOptsFlags-) where--import GHC.Utils.Asm-import GHC.Utils.Error-import GHC.Driver.Session-import GHC.Driver.Ppr-import GHC.Unit.State-import GHC.Platform-import GHC.Utils.Outputable as Outputable-import GHC.Types.SrcLoc ( noSrcSpan )-import GHC.Unit-import GHC.SysTools.Elf-import GHC.Utils.Misc-import GHC.Prelude-import qualified GHC.Data.ShortText as ST--import Control.Monad-import Data.Maybe--import Control.Monad.IO.Class--import GHC.SysTools.FileCleanup-import GHC.SysTools.Tasks-import GHC.SysTools.Info--mkExtraObj :: DynFlags -> Suffix -> String -> IO FilePath-mkExtraObj dflags extn xs- = do cFile <- newTempName dflags TFL_CurrentModule extn- oFile <- newTempName dflags TFL_GhcSession "o"- writeFile cFile xs- ccInfo <- liftIO $ getCompilerInfo dflags- runCc Nothing dflags- ([Option "-c",- FileOption "" cFile,- Option "-o",- FileOption "" oFile]- ++ if extn /= "s"- then cOpts- else asmOpts ccInfo)- return oFile- where- pkgs = unitState dflags-- -- Pass a different set of options to the C compiler depending one whether- -- we're compiling C or assembler. When compiling C, we pass the usual- -- set of include directories and PIC flags.- cOpts = map Option (picCCOpts dflags)- ++ map (FileOption "-I" . ST.unpack)- (unitIncludeDirs $ unsafeLookupUnit pkgs rtsUnit)-- -- When compiling assembler code, we drop the usual C options, and if the- -- compiler is Clang, we add an extra argument to tell Clang to ignore- -- unused command line options. See trac #11684.- asmOpts ccInfo =- if any (ccInfo ==) [Clang, AppleClang, AppleClang51]- then [Option "-Qunused-arguments"]- else []---- When linking a binary, we need to create a C main() function that--- starts everything off. This used to be compiled statically as part--- of the RTS, but that made it hard to change the -rtsopts setting,--- so now we generate and compile a main() stub as part of every--- binary and pass the -rtsopts setting directly to the RTS (#5373)------ On Windows, when making a shared library we also may need a DllMain.----mkExtraObjToLinkIntoBinary :: DynFlags -> IO FilePath-mkExtraObjToLinkIntoBinary dflags = do- when (gopt Opt_NoHsMain dflags && haveRtsOptsFlags dflags) $- putLogMsg dflags NoReason SevInfo noSrcSpan- $ withPprStyle defaultUserStyle- (text "Warning: -rtsopts and -with-rtsopts have no effect with -no-hs-main." $$- text " Call hs_init_ghc() from your main() function to set these options.")-- mkExtraObj dflags "c" (showSDoc dflags main)- where- main- | gopt Opt_NoHsMain dflags = Outputable.empty- | otherwise- = case ghcLink dflags of- LinkDynLib -> if platformOS (targetPlatform dflags) == OSMinGW32- then dllMain- else Outputable.empty- _ -> exeMain-- exeMain = vcat [- text "#include <Rts.h>",- text "extern StgClosure ZCMain_main_closure;",- text "int main(int argc, char *argv[])",- char '{',- text " RtsConfig __conf = defaultRtsConfig;",- text " __conf.rts_opts_enabled = "- <> text (show (rtsOptsEnabled dflags)) <> semi,- text " __conf.rts_opts_suggestions = "- <> text (if rtsOptsSuggestions dflags- then "true"- else "false") <> semi,- text "__conf.keep_cafs = "- <> text (if gopt Opt_KeepCAFs dflags- then "true"- else "false") <> semi,- case rtsOpts dflags of- Nothing -> Outputable.empty- Just opts -> text " __conf.rts_opts= " <>- text (show opts) <> semi,- text " __conf.rts_hs_main = true;",- text " return hs_main(argc,argv,&ZCMain_main_closure,__conf);",- char '}',- char '\n' -- final newline, to keep gcc happy- ]-- dllMain = vcat [- text "#include <Rts.h>",- text "#include <windows.h>",- text "#include <stdbool.h>",- char '\n',- text "bool",- text "WINAPI",- text "DllMain ( HINSTANCE hInstance STG_UNUSED",- text " , DWORD reason STG_UNUSED",- text " , LPVOID reserved STG_UNUSED",- text " )",- text "{",- text " return true;",- text "}",- char '\n' -- final newline, to keep gcc happy- ]---- Write out the link info section into a new assembly file. Previously--- this was included as inline assembly in the main.c file but this--- is pretty fragile. gas gets upset trying to calculate relative offsets--- that span the .note section (notably .text) when debug info is present-mkNoteObjsToLinkIntoBinary :: DynFlags -> [UnitId] -> IO [FilePath]-mkNoteObjsToLinkIntoBinary dflags dep_packages = do- link_info <- getLinkInfo dflags dep_packages-- if (platformSupportsSavingLinkOpts (platformOS platform ))- then fmap (:[]) $ mkExtraObj dflags "s" (showSDoc dflags (link_opts link_info))- else return []-- where- platform = targetPlatform dflags- link_opts info = hcat [- -- "link info" section (see Note [LinkInfo section])- makeElfNote platform ghcLinkInfoSectionName ghcLinkInfoNoteName 0 info,-- -- ALL generated assembly must have this section to disable- -- executable stacks. See also- -- "GHC.CmmToAsm" for another instance- -- where we need to do this.- if platformHasGnuNonexecStack platform- then text ".section .note.GNU-stack,\"\","- <> sectionType platform "progbits" <> char '\n'- else Outputable.empty- ]---- | Return the "link info" string------ See Note [LinkInfo section]-getLinkInfo :: DynFlags -> [UnitId] -> IO String-getLinkInfo dflags dep_packages = do- package_link_opts <- getUnitLinkOpts dflags dep_packages- let unit_state = unitState dflags- home_unit = mkHomeUnitFromFlags dflags- ctx = initSDocContext dflags defaultUserStyle- pkg_frameworks <- if platformUsesFrameworks (targetPlatform dflags)- then getUnitFrameworks ctx unit_state home_unit dep_packages- else return []- let extra_ld_inputs = ldInputs dflags- let- link_info = (package_link_opts,- pkg_frameworks,- rtsOpts dflags,- rtsOptsEnabled dflags,- gopt Opt_NoHsMain dflags,- map showOpt extra_ld_inputs,- getOpts dflags opt_l)- --- return (show link_info)--platformSupportsSavingLinkOpts :: OS -> Bool-platformSupportsSavingLinkOpts os- | os == OSSolaris2 = False -- see #5382- | otherwise = osElfTarget os---- See Note [LinkInfo section]-ghcLinkInfoSectionName :: String-ghcLinkInfoSectionName = ".debug-ghc-link-info"- -- if we use the ".debug" prefix, then strip will strip it by default---- Identifier for the note (see Note [LinkInfo section])-ghcLinkInfoNoteName :: String-ghcLinkInfoNoteName = "GHC link info"---- Returns 'False' if it was, and we can avoid linking, because the--- previous binary was linked with "the same options".-checkLinkInfo :: DynFlags -> [UnitId] -> FilePath -> IO Bool-checkLinkInfo dflags pkg_deps exe_file- | not (platformSupportsSavingLinkOpts (platformOS (targetPlatform dflags)))- -- ToDo: Windows and OS X do not use the ELF binary format, so- -- readelf does not work there. We need to find another way to do- -- this.- = return False -- conservatively we should return True, but not- -- linking in this case was the behaviour for a long- -- time so we leave it as-is.- | otherwise- = do- link_info <- getLinkInfo dflags pkg_deps- debugTraceMsg dflags 3 $ text ("Link info: " ++ link_info)- m_exe_link_info <- readElfNoteAsString dflags exe_file- ghcLinkInfoSectionName ghcLinkInfoNoteName- let sameLinkInfo = (Just link_info == m_exe_link_info)- debugTraceMsg dflags 3 $ case m_exe_link_info of- Nothing -> text "Exe link info: Not found"- Just s- | sameLinkInfo -> text ("Exe link info is the same")- | otherwise -> text ("Exe link info is different: " ++ s)- return (not sameLinkInfo)--{- Note [LinkInfo section]- ~~~~~~~~~~~~~~~~~~~~~~~--The "link info" is a string representing the parameters of the link. We save-this information in the binary, and the next time we link, if nothing else has-changed, we use the link info stored in the existing binary to decide whether-to re-link or not.--The "link info" string is stored in a ELF section called ".debug-ghc-link-info"-(see ghcLinkInfoSectionName) with the SHT_NOTE type. For some time, it used to-not follow the specified record-based format (see #11022).---}--haveRtsOptsFlags :: DynFlags -> Bool-haveRtsOptsFlags dflags =- isJust (rtsOpts dflags) || case rtsOptsEnabled dflags of- RtsOptsSafeOnly -> False- _ -> True
compiler/GHC/SysTools/Tasks.hs view
@@ -26,11 +26,8 @@ import GHC.Utils.Misc import Data.List-import Control.Monad (join, forM, filterM) import System.IO import System.Process-import System.Directory (doesFileExist)-import System.FilePath ((</>)) {- ************************************************************************@@ -239,40 +236,6 @@ llvmVersionStr supportedLlvmVersion) ] return Nothing) ---- | On macOS we rely on the linkers @-dead_strip_dylibs@ flag to remove unused--- libraries from the dynamic library. We do this to reduce the number of load--- commands that end up in the dylib, and has been limited to 32K (32768) since--- macOS Sierra (10.14).------ @-dead_strip_dylibs@ does not dead strip @-rpath@ entries, as such passing--- @-l@ and @-rpath@ to the linker will result in the unnecesasry libraries not--- being included in the load commands, however the @-rpath@ entries are all--- forced to be included. This can lead to 100s of @-rpath@ entries being--- included when only a handful of libraries end up being truely linked.------ Thus after building the library, we run a fixup phase where we inject the--- @-rpath@ for each found library (in the given library search paths) into the--- dynamic library through @-add_rpath@.------ See Note [Dynamic linking on macOS]-runInjectRPaths :: DynFlags -> [FilePath] -> FilePath -> IO ()-runInjectRPaths dflags lib_paths dylib = do- info <- lines <$> askOtool dflags Nothing [Option "-L", Option dylib]- -- filter the output for only the libraries. And then drop the @rpath prefix.- let libs = fmap (drop 7) $ filter (isPrefixOf "@rpath") $ fmap (head.words) $ info- -- find any pre-existing LC_PATH items- info <- fmap words.lines <$> askOtool dflags Nothing [Option "-l", Option dylib]- let paths = concatMap f info- where f ("path":p:_) = [p]- f _ = []- lib_paths' = [ p | p <- lib_paths, not (p `elem` paths) ]- -- only find those rpaths, that aren't already in the library.- rpaths <- nub.sort.join <$> forM libs (\f -> filterM (\l -> doesFileExist (l </> f)) lib_paths')- -- inject the rpaths- case rpaths of- [] -> return ()- _ -> runInstallNameTool dflags $ map Option $ "-add_rpath":(intersperse "-add_rpath" rpaths) ++ [dylib] runLink :: DynFlags -> [Option] -> IO ()
compiler/GHC/Tc/Deriv.hs view
@@ -500,7 +500,7 @@ -- We carefully set up uses of recoverM to minimize error message -- cascades. See Note [Recovering from failures in deriving clauses]. recoverM (pure Nothing) $- setSrcSpan (getLoc (hsSigType deriv_pred)) $ do+ setSrcSpan (getLoc deriv_pred) $ do traceTc "derivePred" $ vcat [ text "tc" <+> ppr tc , text "tys" <+> ppr tys@@ -718,18 +718,15 @@ :: UserTypeCtxt -> LHsSigWcType GhcRn -> TcM ([TyVar], DerivContext, Class, [Type]) tcStandaloneDerivInstType ctxt- (HsWC { hswc_body = deriv_ty@(HsIB { hsib_ext = vars- , hsib_body = deriv_ty_body })})- | (tvs, theta, rho) <- splitLHsSigmaTyInvis deriv_ty_body+ (HsWC { hswc_body = deriv_ty@(L loc (HsSig { sig_bndrs = outer_bndrs+ , sig_body = deriv_ty_body }))})+ | (theta, rho) <- splitLHsQualTy deriv_ty_body , L _ [wc_pred] <- theta , L wc_span (HsWildCardTy _) <- ignoreParens wc_pred- = do dfun_ty <- tcHsClsInstType ctxt $- HsIB { hsib_ext = vars- , hsib_body- = L (getLoc deriv_ty_body) $- HsForAllTy { hst_tele = mkHsForAllInvisTele tvs- , hst_xforall = noExtField- , hst_body = rho }}+ = do dfun_ty <- tcHsClsInstType ctxt $ L loc $+ HsSig { sig_ext = noExtField+ , sig_bndrs = outer_bndrs+ , sig_body = rho } let (tvs, _theta, cls, inst_tys) = tcSplitDFunTy dfun_ty pure (tvs, InferContext (Just wc_span), cls, inst_tys) | otherwise
compiler/GHC/Tc/Deriv/Generate.hs view
@@ -596,7 +596,9 @@ -- mean more tests (dynamically) nlHsIf (ascribeBool $ genPrimOpApp a_expr eq_op b_expr) eq gt where- ascribeBool e = nlExprWithTySig e $ nlHsTyVar boolTyCon_RDR+ ascribeBool e = noLoc $ ExprWithTySig noExtField e+ $ mkHsWildCardBndrs $ noLoc $ mkHsImplicitSigType+ $ nlHsTyVar boolTyCon_RDR nlConWildPat :: DataCon -> LPat GhcPs -- The pattern (K {})@@ -1890,7 +1892,7 @@ -- -- op :: forall c. a -> [T x] -> c -> Int L loc $ ClassOpSig noExtField False [loc_meth_RDR]- $ mkLHsSigType $ nlHsCoreTy to_ty+ $ L loc $ mkHsImplicitSigType $ nlHsCoreTy to_ty ) where Pair from_ty to_ty = mkCoerceClassMethEqn cls inst_tvs inst_tys rhs_ty meth_id@@ -1948,11 +1950,6 @@ where hs_ty = mkHsWildCardBndrs $ parenthesizeHsType appPrec $ nlHsCoreTy s -nlExprWithTySig :: LHsExpr GhcPs -> LHsType GhcPs -> LHsExpr GhcPs-nlExprWithTySig e s = noLoc $ ExprWithTySig noExtField (parenthesizeHsExpr sigPrec e) hs_ty- where- hs_ty = mkLHsSigWcType s- nlHsCoreTy :: Type -> LHsType GhcPs nlHsCoreTy = noLoc . XHsType . NHsCoreTy @@ -2082,19 +2079,21 @@ genAuxBindSpecSig :: SrcSpan -> AuxBindSpec -> LHsSigWcType GhcPs genAuxBindSpecSig loc spec = case spec of DerivCon2Tag tycon _- -> mkLHsSigWcType $ L loc $ XHsType $ NHsCoreTy $+ -> mk_sig $ L loc $ XHsType $ NHsCoreTy $ mkSpecSigmaTy (tyConTyVars tycon) (tyConStupidTheta tycon) $ mkParentType tycon `mkVisFunTyMany` intPrimTy DerivTag2Con tycon _- -> mkLHsSigWcType $ L loc $+ -> mk_sig $ L loc $ XHsType $ NHsCoreTy $ mkSpecForAllTys (tyConTyVars tycon) $ intTy `mkVisFunTyMany` mkParentType tycon DerivMaxTag _ _- -> mkLHsSigWcType (L loc (XHsType (NHsCoreTy intTy)))+ -> mk_sig (L loc (XHsType (NHsCoreTy intTy))) DerivDataDataType _ _ _- -> mkLHsSigWcType (nlHsTyVar dataType_RDR)+ -> mk_sig (nlHsTyVar dataType_RDR) DerivDataConstr _ _ _- -> mkLHsSigWcType (nlHsTyVar constr_RDR)+ -> mk_sig (nlHsTyVar constr_RDR)+ where+ mk_sig = mkHsWildCardBndrs . L loc . mkHsImplicitSigType type SeparateBagsDerivStuff = -- DerivAuxBinds
compiler/GHC/Tc/Errors.hs view
@@ -438,8 +438,13 @@ where tcl_env = ic_env implic insoluble = isInsolubleStatus status- (env1, tvs') = mapAccumL tidyVarBndr (cec_tidy ctxt) tvs- info' = tidySkolemInfo env1 info+ (env1, tvs') = mapAccumL tidyVarBndr (cec_tidy ctxt) $+ scopedSort tvs+ -- scopedSort: the ic_skols may not be in dependency order+ -- (see Note [Skolems in an implication] in GHC.Tc.Types.Constraint)+ -- but tidying goes wrong on out-of-order constraints;+ -- so we sort them here before tidying+ info' = tidySkolemInfo env1 info implic' = implic { ic_skols = tvs' , ic_given = map (tidyEvVar env1) given , ic_info = info' }@@ -507,7 +512,7 @@ = any isImprovementPred (pred : transSuperClasses pred) reportBadTelescope :: ReportErrCtxt -> TcLclEnv -> SkolemInfo -> [TcTyVar] -> TcM ()-reportBadTelescope ctxt env (ForAllSkol _ telescope) skols+reportBadTelescope ctxt env (ForAllSkol telescope) skols = do { msg <- mkErrorReport ctxt env (important doc) ; reportError msg } where
compiler/GHC/Tc/Errors/Hole.hs view
@@ -467,7 +467,7 @@ unwrapTypeVars t = vars ++ case splitFunTy_maybe unforalled of Just (_, _, unfunned) -> unwrapTypeVars unfunned _ -> []- where (vars, unforalled) = splitForAllVarBndrs t+ where (vars, unforalled) = splitForAllTyCoVarBinders t holeVs = sep $ map (parens . (text "_" <+> dcolon <+>) . ppr) hfMatches holeDisp = if sMs then holeVs else sep $ replicate (length hfMatches) $ text "_"
compiler/GHC/Tc/Gen/App.hs view
@@ -450,7 +450,7 @@ -- Rule IALL from Fig 4 of the QL paper go1 delta acc so_far fun_ty args- | (tvs, body1) <- tcSplitSomeForAllTys (inst_fun args) fun_ty+ | (tvs, body1) <- tcSplitSomeForAllTyVars (inst_fun args) fun_ty , (theta, body2) <- tcSplitPhiTy body1 , not (null tvs && null theta) = do { (inst_tvs, wrap, fun_rho) <- setSrcSpanFromArgs rn_args $@@ -556,7 +556,7 @@ -- Deal with a visible type application -- The function type has already had its Inferred binders instantiated tcVTA fun_ty hs_ty- | Just (tvb, inner_ty) <- tcSplitForAllTy_maybe fun_ty+ | Just (tvb, inner_ty) <- tcSplitForAllTyVarBinder_maybe fun_ty , binderArgFlag tvb == Specified -- It really can't be Inferred, because we've just -- instantiated those. But, oddly, it might just be Required.@@ -969,11 +969,11 @@ go bvs fun_ty (EPrag {} : args) = go bvs fun_ty args go bvs fun_ty args@(ETypeArg {} : rest_args)- | (tvs, body1) <- tcSplitSomeForAllTys (== Inferred) fun_ty+ | (tvs, body1) <- tcSplitSomeForAllTyVars (== Inferred) fun_ty , (theta, body2) <- tcSplitPhiTy body1 , not (null tvs && null theta) = go (bvs `extendVarSetList` tvs) body2 args- | Just (_tv, res_ty) <- tcSplitForAllTy_maybe fun_ty+ | Just (_tv, res_ty) <- tcSplitForAllTyVarBinder_maybe fun_ty = go bvs res_ty rest_args | otherwise = False -- E.g. head ids @Int
compiler/GHC/Tc/Gen/Bind.hs view
@@ -1659,7 +1659,7 @@ = [ null theta | TcIdSig (PartialSig { psig_hs_ty = hs_ty }) <- mapMaybe sig_fn (collectHsBindListBinders lbinds)- , let (_, L _ theta, _) = splitLHsSigmaTyInvis (hsSigWcType hs_ty) ]+ , let (L _ theta, _) = splitLHsQualTy (hsSigWcType hs_ty) ] has_partial_sigs = not (null partial_sig_mrs)
compiler/GHC/Tc/Gen/Foreign.hs view
@@ -124,7 +124,7 @@ | Just (tc, tys) <- splitTyConApp_maybe ty = go_tc_app role rec_nts tc tys - | (bndrs, inner_ty) <- splitForAllVarBndrs ty+ | (bndrs, inner_ty) <- splitForAllTyCoVarBinders ty , not (null bndrs) = do (coi, nty1, gres1) <- go role rec_nts inner_ty return ( mkHomoForAllCos (binderVars bndrs) coi
compiler/GHC/Tc/Gen/Head.hs view
@@ -632,7 +632,7 @@ ; (expr', poly_ty) <- tcExprSig expr sig_info ; return (ExprWithTySig noExtField expr' hs_ty, poly_ty) } where- loc = getLoc (hsSigWcType hs_ty)+ loc = getLoc (dropWildCards hs_ty) tcExprSig :: LHsExpr GhcRn -> TcIdSigInfo -> TcM (LHsExpr GhcTc, TcType) tcExprSig expr (CompleteSig { sig_bndr = poly_id, sig_loc = loc })
compiler/GHC/Tc/Gen/HsType.hs view
@@ -29,8 +29,13 @@ bindImplicitTKBndrs_Q_Tv, bindImplicitTKBndrs_Q_Skol, bindExplicitTKBndrs_Tv, bindExplicitTKBndrs_Skol, bindExplicitTKBndrs_Q_Tv, bindExplicitTKBndrs_Q_Skol,- ContextKind(..), + bindOuterFamEqnTKBndrs, bindOuterFamEqnTKBndrs_Q_Tv,+ tcOuterTKBndrs, scopedSortOuter,+ bindOuterSigTKBndrs_Tv,+ tcExplicitTKBndrs,+ bindNamedWildCardBinders,+ -- Type checking type and class decls, and instances thereof bindTyClTyVars, tcFamTyPats, etaExpandAlgTyCon, tcbVisibilities,@@ -42,8 +47,8 @@ -- No kind generalisation, no checkValidType InitialKindStrategy(..), SAKS_or_CUSK(..),+ ContextKind(..), kcDeclHeader,- tcNamedWildCardBinders, tcHsLiftedType, tcHsOpenType, tcHsLiftedTypeNC, tcHsOpenTypeNC, tcInferLHsTypeKind, tcInferLHsType, tcInferLHsTypeUnsaturated,@@ -335,13 +340,13 @@ funsSigCtxt (L _ name1 : _) = FunSigCtxt name1 False funsSigCtxt [] = panic "funSigCtxt" -addSigCtxt :: UserTypeCtxt -> LHsType GhcRn -> TcM a -> TcM a+addSigCtxt :: Outputable hs_ty => UserTypeCtxt -> Located hs_ty -> TcM a -> TcM a addSigCtxt ctxt hs_ty thing_inside = setSrcSpan (getLoc hs_ty) $ addErrCtxt (pprSigCtxt ctxt hs_ty) $ thing_inside -pprSigCtxt :: UserTypeCtxt -> LHsType GhcRn -> SDoc+pprSigCtxt :: Outputable hs_ty => UserTypeCtxt -> Located hs_ty -> SDoc -- (pprSigCtxt ctxt <extra> <type>) -- prints In the type signature for 'f': -- f :: <type>@@ -361,9 +366,9 @@ -- already checked this, so we can simply ignore it. tcHsSigWcType ctxt sig_ty = tcHsSigType ctxt (dropWildCards sig_ty) -kcClassSigType :: SkolemInfo -> [Located Name] -> LHsSigType GhcRn -> TcM ()+kcClassSigType :: [Located Name] -> LHsSigType GhcRn -> TcM () -- This is a special form of tcClassSigType that is used during the--- kind-checking phase to infer the kind of class variables. Cf. tc_hs_sig_type.+-- kind-checking phase to infer the kind of class variables. Cf. tc_lhs_sig_type. -- Importantly, this does *not* kind-generalize. Consider -- class SC f where -- meth :: forall a (x :: f a). Proxy x -> ()@@ -374,21 +379,18 @@ -- end up promoting kappa to the top level (because kind-generalization is -- normally done right before adding a binding to the context), and then we -- can't set kappa := f a, because a is local.-kcClassSigType skol_info names (HsIB { hsib_ext = sig_vars- , hsib_body = hs_ty })- = addSigCtxt (funsSigCtxt names) hs_ty $- do { (tc_lvl, wanted, (spec_tkvs, _))- <- pushLevelAndSolveEqualitiesX "kcClassSigType" $- bindImplicitTKBndrs_Skol sig_vars $+kcClassSigType names+ sig_ty@(L _ (HsSig { sig_bndrs = hs_outer_bndrs, sig_body = hs_ty }))+ = addSigCtxt (funsSigCtxt names) sig_ty $+ do { _ <- bindOuterSigTKBndrs_Tv hs_outer_bndrs $ tcLHsType hs_ty liftedTypeKind-- ; emitResidualTvConstraint skol_info spec_tkvs tc_lvl wanted }+ ; return () } -tcClassSigType :: SkolemInfo -> [Located Name] -> LHsSigType GhcRn -> TcM Type+tcClassSigType :: [Located Name] -> LHsSigType GhcRn -> TcM Type -- Does not do validity checking-tcClassSigType skol_info names sig_ty- = addSigCtxt (funsSigCtxt names) (hsSigType sig_ty) $- do { (implic, ty) <- tc_hs_sig_type skol_info sig_ty (TheKind liftedTypeKind)+tcClassSigType names sig_ty+ = addSigCtxt sig_ctxt sig_ty $+ do { (implic, ty) <- tc_lhs_sig_type skol_info sig_ty (TheKind liftedTypeKind) ; emitImplication implic ; return ty } -- Do not zonk-to-Type, nor perform a validity check@@ -407,20 +409,24 @@ -- It should be that f has kind `k2 -> *`, but we never get a chance -- to run the solver where the kind of f is touchable. This is -- painfully delicate.+ where+ sig_ctxt = funsSigCtxt names+ skol_info = SigTypeSkol sig_ctxt tcHsSigType :: UserTypeCtxt -> LHsSigType GhcRn -> TcM Type -- Does validity checking -- See Note [Recipe for checking a signature] tcHsSigType ctxt sig_ty- = addSigCtxt ctxt (hsSigType sig_ty) $+ = addSigCtxt ctxt sig_ty $ do { traceTc "tcHsSigType {" (ppr sig_ty) -- Generalise here: see Note [Kind generalisation]- ; (implic, ty) <- tc_hs_sig_type skol_info sig_ty (expectedKindInCtxt ctxt)+ ; (implic, ty) <- tc_lhs_sig_type skol_info sig_ty (expectedKindInCtxt ctxt) - -- Spit out the implication (and perhaps fail fast)+ -- Float out constraints, failing fast if not possible -- See Note [Failure in local type signatures] in GHC.Tc.Solver- ; emitFlatConstraints (mkImplicWC (unitBag implic))+ ; traceTc "tcHsSigType 2" (ppr implic)+ ; simplifyAndEmitFlatConstraints (mkImplicWC (unitBag implic)) ; ty <- zonkTcType ty ; checkValidType ctxt ty@@ -429,7 +435,7 @@ where skol_info = SigTypeSkol ctxt -tc_hs_sig_type :: SkolemInfo -> LHsSigType GhcRn+tc_lhs_sig_type :: SkolemInfo -> LHsSigType GhcRn -> ContextKind -> TcM (Implication, TcType) -- Kind-checks/desugars an 'LHsSigType', -- solve equalities,@@ -437,25 +443,28 @@ -- This will never emit constraints, as it uses solveEqualities internally. -- No validity checking or zonking -- Returns also an implication for the unsolved constraints-tc_hs_sig_type skol_info hs_sig_type ctxt_kind- | HsIB { hsib_ext = sig_vars, hsib_body = hs_ty } <- hs_sig_type- = do { (tc_lvl, wanted, (spec_tkvs, ty))- <- pushLevelAndSolveEqualitiesX "tc_hs_sig_type" $+tc_lhs_sig_type skol_info (L loc (HsSig { sig_bndrs = hs_outer_bndrs+ , sig_body = hs_ty })) ctxt_kind+ = setSrcSpan loc $+ do { (tc_lvl, wanted, (outer_bndrs, ty))+ <- pushLevelAndSolveEqualitiesX "tc_lhs_sig_type" $ -- See Note [Failure in local type signatures]- bindImplicitTKBndrs_Skol sig_vars $+ tcOuterTKBndrs skol_info hs_outer_bndrs $ do { kind <- newExpectedKind ctxt_kind ; tcLHsType hs_ty kind } -- Any remaining variables (unsolved in the solveEqualities) -- should be in the global tyvars, and therefore won't be quantified - ; spec_tkvs <- zonkAndScopedSort spec_tkvs- ; let ty1 = mkSpecForAllTys spec_tkvs ty+ ; traceTc "tc_lhs_sig_type" (ppr hs_outer_bndrs $$ ppr outer_bndrs)+ ; (outer_tv_bndrs :: [InvisTVBinder]) <- scopedSortOuter outer_bndrs + ; let ty1 = mkInvisForAllTys outer_tv_bndrs ty+ ; kvs <- kindGeneralizeSome wanted ty1 -- Build an implication for any as-yet-unsolved kind equalities -- See Note [Skolem escape in type signatures]- ; implic <- buildTvImplication skol_info (kvs ++ spec_tkvs) tc_lvl wanted+ ; implic <- buildTvImplication skol_info kvs tc_lvl wanted ; return (implic, mkInfForAllTys kvs ty1) } @@ -466,23 +475,24 @@ This is ill-kinded becuase of a nested skolem-escape. That will show up as an un-solvable constraint in the implication-returned by buildTvImplication in tc_hs_sig_type. See Note [Skolem+returned by buildTvImplication in tc_lhs_sig_type. See Note [Skolem escape prevention] in GHC.Tc.Utils.TcType for why it is unsolvable (the unification variable for b's kind is untouchable). -Then, in GHC.Tc.Solver.emitFlatConstraints (called from tcHsSigType)+Then, in GHC.Tc.Solver.simplifyAndEmitFlatConstraints (called from tcHsSigType) we'll try to float out the constraint, be unable to do so, and fail. See GHC.Tc.Solver Note [Failure in local type signatures] for more detail on this. -The separation between tcHsSigType and tc_hs_sig_type is because+The separation between tcHsSigType and tc_lhs_sig_type is because tcClassSigType wants to use the latter, but *not* fail fast, because there are skolems from the class decl which are in scope; but it's fine not to because tcClassDecl1 has a solveEqualities wrapped around all the tcClassSigType calls. -That's why tcHsSigType does emitFlatConstraints (which fails fast) but-tcClassSigType just does emitImplication (which does not). Ugh.+That's why tcHsSigType does simplifyAndEmitFlatConstraints (which+fails fast) but tcClassSigType just does emitImplication (which does+not). Ugh. c.f. see also Note [Skolem escape and forall-types]. The difference is that we don't need to simplify at a forall type, only at the@@ -491,45 +501,46 @@ -- Does validity checking and zonking. tcStandaloneKindSig :: LStandaloneKindSig GhcRn -> TcM (Name, Kind)-tcStandaloneKindSig (L _ kisig) = case kisig of- StandaloneKindSig _ (L _ name) ksig ->- let ctxt = StandaloneKindSigCtxt name in- addSigCtxt ctxt (hsSigType ksig) $- do { let mode = mkMode KindLevel- ; kind <- tc_top_lhs_type mode ksig (expectedKindInCtxt ctxt)+tcStandaloneKindSig (L _ (StandaloneKindSig _ (L _ name) ksig))+ = addSigCtxt ctxt ksig $+ do { kind <- tc_top_lhs_type KindLevel ctxt ksig ; checkValidType ctxt kind ; return (name, kind) }-+ where+ ctxt = StandaloneKindSigCtxt name -tcTopLHsType :: LHsSigType GhcRn -> ContextKind -> TcM Type-tcTopLHsType hs_ty ctxt_kind- = tc_top_lhs_type (mkMode TypeLevel) hs_ty ctxt_kind+tcTopLHsType :: UserTypeCtxt -> LHsSigType GhcRn -> TcM Type+tcTopLHsType ctxt lsig_ty+ = tc_top_lhs_type TypeLevel ctxt lsig_ty -tc_top_lhs_type :: TcTyMode -> LHsSigType GhcRn -> ContextKind -> TcM Type--- tcTopLHsType is used for kind-checking top-level HsType where+tc_top_lhs_type :: TypeOrKind -> UserTypeCtxt -> LHsSigType GhcRn -> TcM Type+-- tc_top_lhs_type is used for kind-checking top-level LHsSigTypes where -- we want to fully solve /all/ equalities, and report errors -- Does zonking, but not validity checking because it's used -- for things (like deriving and instances) that aren't -- ordinary types -- Used for both types and kinds-tc_top_lhs_type mode hs_sig_type ctxt_kind- | HsIB { hsib_ext = sig_vars, hsib_body = hs_ty } <- hs_sig_type- = do { traceTc "tcTopLHsType {" (ppr hs_ty)- ; (tclvl, wanted, (spec_tkvs, ty))- <- pushLevelAndSolveEqualitiesX "tc_top_lhs_type" $- bindImplicitTKBndrs_Skol sig_vars $- do { kind <- newExpectedKind ctxt_kind- ; tc_lhs_type mode hs_ty kind }+tc_top_lhs_type tyki ctxt (L loc sig_ty@(HsSig { sig_bndrs = hs_outer_bndrs+ , sig_body = body }))+ = setSrcSpan loc $+ do { traceTc "tc_top_lhs_type {" (ppr sig_ty)+ ; (tclvl, wanted, (outer_bndrs, ty))+ <- pushLevelAndSolveEqualitiesX "tc_top_lhs_type" $+ tcOuterTKBndrs skol_info hs_outer_bndrs $+ do { kind <- newExpectedKind (expectedKindInCtxt ctxt)+ ; tc_lhs_type (mkMode tyki) body kind } - ; spec_tkvs <- zonkAndScopedSort spec_tkvs- ; reportUnsolvedEqualities InstSkol spec_tkvs tclvl wanted+ ; outer_tv_bndrs <- scopedSortOuter outer_bndrs+ ; let ty1 = mkInvisForAllTys outer_tv_bndrs ty - ; let ty1 = mkSpecForAllTys spec_tkvs ty- ; kvs <- kindGeneralizeAll ty1+ ; kvs <- kindGeneralizeAll ty1 -- "All" because it's a top-level type+ ; reportUnsolvedEqualities skol_info kvs tclvl wanted ; final_ty <- zonkTcTypeToType (mkInfForAllTys kvs ty1)- ; traceTc "End tcTopLHsType }" (vcat [ppr hs_ty, ppr final_ty])- ; return final_ty}+ ; traceTc "tc_top_lhs_type }" (vcat [ppr sig_ty, ppr final_ty])+ ; return final_ty }+ where+ skol_info = SigTypeSkol ctxt ----------------- tcHsDeriv :: LHsSigType GhcRn -> TcM ([TyVar], Class, [Type], [Kind])@@ -542,8 +553,8 @@ tcHsDeriv hs_ty = do { ty <- checkNoErrs $ -- Avoid redundant error report -- with "illegal deriving", below- tcTopLHsType hs_ty AnyKind- ; let (tvs, pred) = splitForAllTys ty+ tcTopLHsType DerivClauseCtxt hs_ty+ ; let (tvs, pred) = splitForAllTyCoVars ty (kind_args, _) = splitFunTys (tcTypeKind pred) ; case getClassPredTys_maybe pred of Just (cls, tys) -> return (tvs, cls, tys, map scaledThing kind_args)@@ -571,8 +582,8 @@ tc_deriv_strategy AnyclassStrategy = boring_case AnyclassStrategy tc_deriv_strategy NewtypeStrategy = boring_case NewtypeStrategy tc_deriv_strategy (ViaStrategy ty) = do- ty' <- checkNoErrs $ tcTopLHsType ty AnyKind- let (via_tvs, via_pred) = splitForAllTys ty'+ ty' <- checkNoErrs $ tcTopLHsType DerivClauseCtxt ty+ let (via_tvs, via_pred) = splitForAllTyCoVars ty' pure (ViaStrategy via_pred, via_tvs) boring_case :: ds -> TcM (ds, [TyVar])@@ -583,13 +594,13 @@ -> TcM Type -- Like tcHsSigType, but for a class instance declaration tcHsClsInstType user_ctxt hs_inst_ty- = setSrcSpan (getLoc (hsSigType hs_inst_ty)) $+ = setSrcSpan (getLoc hs_inst_ty) $ do { -- Fail eagerly if tcTopLHsType fails. We are at top level so -- these constraints will never be solved later. And failing -- eagerly avoids follow-on errors when checkValidInstance -- sees an unsolved coercion hole inst_ty <- checkNoErrs $- tcTopLHsType hs_inst_ty (TheKind constraintKind)+ tcTopLHsType user_ctxt hs_inst_ty ; checkValidInstance user_ctxt hs_inst_ty inst_ty ; return inst_ty } @@ -605,7 +616,7 @@ solveEqualities "tcHsTypeApp" $ -- We are looking at a user-written type, very like a -- signature so we want to solve its equalities right now- tcNamedWildCardBinders sig_wcs $ \ _ ->+ bindNamedWildCardBinders sig_wcs $ \ _ -> tc_lhs_type mode hs_ty kind -- We do not kind-generalize type applications: we just@@ -713,7 +724,7 @@ tcInferLHsTypeKind lhs_ty@(L loc hs_ty) = addTypeCtxt lhs_ty $ setSrcSpan loc $ -- Cover the tcInstInvisibleTyBinders- do { (res_ty, res_kind) <- tc_infer_hs_type (mkMode TypeLevel) hs_ty+ do { (res_ty, res_kind) <- tc_infer_hs_type typeLevelMode hs_ty ; tcInstInvisibleTyBinders res_ty res_kind } -- See Note [Do not always instantiate eagerly in types] @@ -783,7 +794,7 @@ -} tcMult :: HsArrow GhcRn -> TcM Mult-tcMult hc = tc_mult (mkMode TypeLevel) hc+tcMult hc = tc_mult typeLevelMode hc -- | Info about the context in which we're checking a type. Currently, -- differentiates only between types and kinds, but this will likely@@ -795,11 +806,11 @@ -- This data type is purely local, not exported from this module data TcTyMode = TcTyMode { mode_tyki :: TypeOrKind+ , mode_holes :: HoleInfo } - -- See Note [Levels for wildcards]- -- Nothing <=> no wildcards expected- , mode_holes :: Maybe (TcLevel, HoleMode)- }+-- See Note [Levels for wildcards]+-- Nothing <=> no wildcards expected+type HoleInfo = Maybe (TcLevel, HoleMode) -- HoleMode says how to treat the occurrences -- of anonymous wildcards; see tcAnonWildCardOcc@@ -812,15 +823,17 @@ mkMode :: TypeOrKind -> TcTyMode mkMode tyki = TcTyMode { mode_tyki = tyki, mode_holes = Nothing } +typeLevelMode, kindLevelMode :: TcTyMode+-- These modes expect no wildcards (holes) in the type+kindLevelMode = mkMode KindLevel+typeLevelMode = mkMode TypeLevel+ mkHoleMode :: TypeOrKind -> HoleMode -> TcM TcTyMode mkHoleMode tyki hm = do { lvl <- getTcLevel ; return (TcTyMode { mode_tyki = tyki , mode_holes = Just (lvl,hm) }) } -kindLevel :: TcTyMode -> TcTyMode-kindLevel mode = mode { mode_tyki = KindLevel }- instance Outputable HoleMode where ppr HM_Sig = text "HM_Sig" ppr HM_FamPat = text "HM_FamPat"@@ -997,7 +1010,7 @@ ------------------------------------------ tcLHsType :: LHsType GhcRn -> TcKind -> TcM TcType tcLHsType hs_ty exp_kind- = tc_lhs_type (mkMode TypeLevel) hs_ty exp_kind+ = tc_lhs_type typeLevelMode hs_ty exp_kind tc_lhs_type :: TcTyMode -> LHsType GhcRn -> TcKind -> TcM TcType tc_lhs_type mode (L span ty) exp_kind@@ -1049,32 +1062,16 @@ = tc_fun_type mode (HsUnrestrictedArrow NormalSyntax) ty1 ty2 exp_kind --------- Foralls-tc_hs_type mode forall@(HsForAllTy { hst_tele = tele, hst_body = ty }) exp_kind- = do { (tclvl, wanted, (tv_bndrs, ty'))- <- pushLevelAndCaptureConstraints $- -- No need to solve equalities here; we will do that later- bindExplicitTKTele_Skol_M mode tele $- -- The _M variant passes on the mode from the type, to- -- any wildards in kind signatures on the forall'd variables+tc_hs_type mode (HsForAllTy { hst_tele = tele, hst_body = ty }) exp_kind+ = do { (tv_bndrs, ty') <- tcTKTelescope mode tele $+ tc_lhs_type mode ty exp_kind+ -- Pass on the mode from the type, to any wildcards+ -- in kind signatures on the forall'd variables -- e.g. f :: _ -> Int -> forall (a :: _). blah- tc_lhs_type mode ty exp_kind -- Why exp_kind? See Note [Body kind of HsForAllTy] -- Do not kind-generalise here! See Note [Kind generalisation] - ; let skol_info = ForAllSkol (ppr forall) $ sep $ case tele of- HsForAllVis { hsf_vis_bndrs = hs_tvs } ->- map ppr hs_tvs- HsForAllInvis { hsf_invis_bndrs = hs_tvs } ->- map ppr hs_tvs- skol_tvs = binderVars tv_bndrs-- ; implic <- buildTvImplication skol_info skol_tvs tclvl wanted- ; emitImplication implic- -- /Always/ emit this implication even if wanted is empty- -- We need the implication so that we check for a bad telescope- -- See Note [Skolem escape and forall-types]- ; return (mkForAllTys tv_bndrs ty') } tc_hs_type mode (HsQualTy { hst_ctxt = ctxt, hst_body = rn_ty }) exp_kind@@ -1824,10 +1821,10 @@ tcHsMbContext (Just cxt) = tcHsContext cxt tcHsContext :: LHsContext GhcRn -> TcM [PredType]-tcHsContext cxt = tc_hs_context (mkMode TypeLevel) cxt+tcHsContext cxt = tc_hs_context typeLevelMode cxt tcLHsPredType :: LHsType GhcRn -> TcM PredType-tcLHsPredType pred = tc_lhs_pred (mkMode TypeLevel) pred+tcLHsPredType pred = tc_lhs_pred typeLevelMode pred tc_hs_context :: TcTyMode -> LHsContext GhcRn -> TcM [PredType] tc_hs_context mode ctxt = mapM (tc_lhs_pred mode) (unLoc ctxt)@@ -2051,13 +2048,13 @@ * * ********************************************************************* -} -tcNamedWildCardBinders :: [Name]- -> ([(Name, TcTyVar)] -> TcM a)- -> TcM a+bindNamedWildCardBinders :: [Name]+ -> ([(Name, TcTyVar)] -> TcM a)+ -> TcM a -- Bring into scope the /named/ wildcard binders. Remember that -- plain wildcards _ are anonymous and dealt with by HsWildCardTy -- Soe Note [The wildcard story for types] in GHC.Hs.Type-tcNamedWildCardBinders wc_names thing_inside+bindNamedWildCardBinders wc_names thing_inside = do { wcs <- mapM newNamedWildTyVar wc_names ; let wc_prs = wc_names `zip` wcs ; tcExtendNameTyVarEnv wc_prs $@@ -2351,7 +2348,7 @@ all_tv_prs = mkTyVarNamePairs (scoped_kvs ++ tc_tvs) -- NB: bindExplicitTKBndrs_Q_Tv does not clone; -- ditto Implicit- -- See Note [Non-cloning for tyvar binders]+ -- See Note [Cloning for type variable binders] tycon = mkTcTyCon name tc_binders res_kind all_tv_prs False -- not yet generalised@@ -2571,13 +2568,13 @@ split_invis :: Kind -> Maybe Kind -> ([TyCoBinder], Kind) split_invis sig_ki Nothing = -- instantiate all invisible binders- splitPiTysInvisible sig_ki+ splitInvisPiTys sig_ki split_invis sig_ki (Just res_ki) = -- subtraction a la checkExpectedKind let n_res_invis_bndrs = invisibleTyBndrCount res_ki n_sig_invis_bndrs = invisibleTyBndrCount sig_ki n_inst = n_sig_invis_bndrs - n_res_invis_bndrs- in splitPiTysInvisibleN n_inst sig_ki+ in splitInvisPiTysN n_inst sig_ki -- A quantifier from a kind signature zipped with a user-written binder for it. data ZippedBinder =@@ -2897,6 +2894,7 @@ -- The types in a 'default' decl can have varying kinds -- See Note [Extended defaults]" in GHC.Tc.Utils.Env expectedKindInCtxt DefaultDeclCtxt = AnyKind+expectedKindInCtxt DerivClauseCtxt = AnyKind expectedKindInCtxt TypeAppCtxt = AnyKind expectedKindInCtxt (ForSigCtxt _) = TheKind liftedTypeKind expectedKindInCtxt (InstDeclCtxt {}) = TheKind constraintKind@@ -2910,230 +2908,413 @@ * * ********************************************************************* -} -{- Note [Non-cloning for tyvar binders]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-bindExplictTKBndrs_Q_Skol, bindExplictTKBndrs_Skol, do not clone;-and nor do the Implicit versions. There is no need.+--------------------------------------+-- HsForAllTelescope+-------------------------------------- -bindExplictTKBndrs_Q_Tv does not clone; and similarly Implicit.-We take advantage of this in kcInferDeclHeader:- all_tv_prs = mkTyVarNamePairs (scoped_kvs ++ tc_tvs)-If we cloned, we'd need to take a bit more care here; not hard.+tcTKTelescope :: TcTyMode+ -> HsForAllTelescope GhcRn+ -> TcM a+ -> TcM ([TcTyVarBinder], a)+tcTKTelescope mode tele thing_inside = case tele of+ HsForAllVis { hsf_vis_bndrs = bndrs }+ -> do { (req_tv_bndrs, thing) <- tcExplicitTKBndrsX skol_mode bndrs thing_inside+ -- req_tv_bndrs :: [VarBndr TyVar ()],+ -- but we want [VarBndr TyVar ArgFlag]+ ; return (tyVarReqToBinders req_tv_bndrs, thing) } -The main payoff is that avoidng gratuitious cloning means that we can-almost always take the fast path in swizzleTcTyConBndrs. "Almost-always" means not the case of mutual recursion with polymorphic kinds.+ HsForAllInvis { hsf_invis_bndrs = bndrs }+ -> do { (inv_tv_bndrs, thing) <- tcExplicitTKBndrsX skol_mode bndrs thing_inside+ -- inv_tv_bndrs :: [VarBndr TyVar Specificity],+ -- but we want [VarBndr TyVar ArgFlag]+ ; return (tyVarSpecToBinders inv_tv_bndrs, thing) }+ where+ skol_mode = smVanilla { sm_clone = False, sm_holes = mode_holes mode } +--------------------------------------+-- HsOuterTyVarBndrs+-------------------------------------- -Note [Cloning for tyvar binders]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-bindExplicitTKBndrs_Tv does cloning, making up a Name with a fresh Unique,-unlike bindExplicitTKBndrs_Q_Tv. (Nor do the Skol variants clone.)-And similarly for bindImplicit...+bindOuterTKBndrsX :: OutputableBndrFlag flag+ => SkolemMode+ -> HsOuterTyVarBndrs flag GhcRn+ -> TcM a+ -> TcM (HsOuterTyVarBndrs flag GhcTc, a)+bindOuterTKBndrsX skol_mode outer_bndrs thing_inside+ = case outer_bndrs of+ HsOuterImplicit{hso_ximplicit = imp_tvs} ->+ do { (imp_tvs', thing) <- bindImplicitTKBndrsX skol_mode imp_tvs thing_inside+ ; return ( HsOuterImplicit{hso_ximplicit = imp_tvs'}+ , thing) }+ HsOuterExplicit{hso_bndrs = exp_bndrs} ->+ do { (exp_tvs', thing) <- bindExplicitTKBndrsX skol_mode exp_bndrs thing_inside+ ; return ( HsOuterExplicit { hso_xexplicit = exp_tvs'+ , hso_bndrs = exp_bndrs }+ , thing) } -This for a narrow and tricky reason which, alas, I couldn't find a-simpler way round. #16221 is the poster child:+getOuterTyVars :: HsOuterTyVarBndrs flag GhcTc -> [TcTyVar]+-- The returned [TcTyVar] is not necessarily in dependency order+-- at least for the HsOuterImplicit case+getOuterTyVars (HsOuterImplicit { hso_ximplicit = tvs }) = tvs+getOuterTyVars (HsOuterExplicit { hso_xexplicit = tvbs }) = binderVars tvbs - data SameKind :: k -> k -> *- data T a = forall k2 (b :: k2). MkT (SameKind a b) !Int+---------------+scopedSortOuter :: HsOuterTyVarBndrs Specificity GhcTc -> TcM [InvisTVBinder]+-- Sort any /implicit/ binders into dependency order+-- (zonking first so we can see the dependencies)+-- /Explicit/ ones are already in the right order+scopedSortOuter (HsOuterImplicit{hso_ximplicit = imp_tvs})+ = do { imp_tvs <- zonkAndScopedSort imp_tvs+ ; return [Bndr tv SpecifiedSpec | tv <- imp_tvs] }+scopedSortOuter (HsOuterExplicit{hso_xexplicit = exp_tvs})+ = -- No need to dependency-sort (or zonk) explicit quantifiers+ return exp_tvs -When kind-checking T, we give (a :: kappa1). Then:+---------------+bindOuterSigTKBndrs_Tv :: HsOuterSigTyVarBndrs GhcRn+ -> TcM a -> TcM (HsOuterSigTyVarBndrs GhcTc, a)+bindOuterSigTKBndrs_Tv+ = bindOuterTKBndrsX (smVanilla { sm_clone = True, sm_tvtv = True }) -- In kcConDecl we make a TyVarTv unification variable kappa2 for k2- (as described in Note [Kind-checking for GADTs], even though this- example is an existential)-- So we get (b :: kappa2) via bindExplicitTKBndrs_Tv-- We end up unifying kappa1 := kappa2, because of the (SameKind a b)+bindOuterSigTKBndrs_Tv_M :: TcTyMode+ -> HsOuterSigTyVarBndrs GhcRn+ -> TcM a -> TcM (HsOuterSigTyVarBndrs GhcTc, a)+-- Do not push level; do not make implication constraint; use Tvs+-- Two major clients of this "bind-only" path are:+-- Note [Kind-checking for GADTs] in TyCl+-- Note [Checking partial type signatures]+bindOuterSigTKBndrs_Tv_M mode+ = bindOuterTKBndrsX (smVanilla { sm_clone = True, sm_tvtv = True+ , sm_holes = mode_holes mode }) -Now we generalise over kappa2. But if kappa2's Name is precisely k2-(i.e. we did not clone) we'll end up giving T the utterlly final kind- T :: forall k2. k2 -> *-Nothing directly wrong with that but when we typecheck the data constructor-we have k2 in scope; but then it's brought into scope /again/ when we find-the forall k2. This is chaotic, and we end up giving it the type- MkT :: forall k2 (a :: k2) k2 (b :: k2).- SameKind @k2 a b -> Int -> T @{k2} a-which is bogus -- because of the shadowing of k2, we can't-apply T to the kind or a!+bindOuterFamEqnTKBndrs_Q_Tv :: HsOuterFamEqnTyVarBndrs GhcRn+ -> TcM a+ -> TcM ([TcTyVar], a)+bindOuterFamEqnTKBndrs_Q_Tv hs_bndrs thing_inside+ = liftFstM getOuterTyVars $+ bindOuterTKBndrsX (smVanilla { sm_clone = False, sm_parent = True+ , sm_tvtv = True })+ hs_bndrs thing_inside+ -- sm_clone=False: see Note [Cloning for type variable binders] -And there no reason /not/ to clone the Name when making a unification-variable. So that's what we do.--}+bindOuterFamEqnTKBndrs :: HsOuterFamEqnTyVarBndrs GhcRn+ -> TcM a+ -> TcM ([TcTyVar], a)+bindOuterFamEqnTKBndrs hs_bndrs thing_inside+ = liftFstM getOuterTyVars $+ bindOuterTKBndrsX (smVanilla { sm_clone = False, sm_parent = True })+ hs_bndrs thing_inside+ -- sm_clone=False: see Note [Cloning for type variable binders] +---------------+tcOuterTKBndrs :: OutputableBndrFlag flag+ => SkolemInfo+ -> HsOuterTyVarBndrs flag GhcRn+ -> TcM a -> TcM (HsOuterTyVarBndrs flag GhcTc, a)+tcOuterTKBndrs = tcOuterTKBndrsX (smVanilla { sm_clone = False })+ -- Do not clone the outer binders+ -- See Note [Cloning for type variable binder] under "must not"++tcOuterTKBndrsX :: OutputableBndrFlag flag+ => SkolemMode -> SkolemInfo+ -> HsOuterTyVarBndrs flag GhcRn+ -> TcM a -> TcM (HsOuterTyVarBndrs flag GhcTc, a)+-- Push level, capture constraints, make implication+tcOuterTKBndrsX skol_mode skol_info outer_bndrs thing_inside+ = case outer_bndrs of+ HsOuterImplicit{hso_ximplicit = imp_tvs} ->+ do { (imp_tvs', thing) <- tcImplicitTKBndrsX skol_mode skol_info imp_tvs thing_inside+ ; return ( HsOuterImplicit{hso_ximplicit = imp_tvs'}+ , thing) }+ HsOuterExplicit{hso_bndrs = exp_bndrs} ->+ do { (exp_tvs', thing) <- tcExplicitTKBndrsX skol_mode exp_bndrs thing_inside+ ; return ( HsOuterExplicit { hso_xexplicit = exp_tvs'+ , hso_bndrs = exp_bndrs }+ , thing) }+ ----------------------------------------- Implicit binders+-- Explicit tyvar binders -------------------------------------- -bindImplicitTKBndrs_Skol, bindImplicitTKBndrs_Tv,- bindImplicitTKBndrs_Q_Skol, bindImplicitTKBndrs_Q_Tv- :: [Name] -> TcM a -> TcM ([TcTyVar], a)-bindImplicitTKBndrs_Q_Skol = bindImplicitTKBndrsX (newImplicitTyVarQ newFlexiKindedSkolemTyVar)-bindImplicitTKBndrs_Q_Tv = bindImplicitTKBndrsX (newImplicitTyVarQ newFlexiKindedTyVarTyVar)-bindImplicitTKBndrs_Skol = bindImplicitTKBndrsX newFlexiKindedSkolemTyVar-bindImplicitTKBndrs_Tv = bindImplicitTKBndrsX cloneFlexiKindedTyVarTyVar- -- newFlexiKinded... see Note [Non-cloning for tyvar binders]- -- cloneFlexiKindedTyVarTyVar: see Note [Cloning for tyvar binders]+tcExplicitTKBndrs :: OutputableBndrFlag flag+ => [LHsTyVarBndr flag GhcRn]+ -> TcM a+ -> TcM ([VarBndr TyVar flag], a)+tcExplicitTKBndrs = tcExplicitTKBndrsX (smVanilla { sm_clone = True }) -bindImplicitTKBndrsX- :: (Name -> TcM TcTyVar) -- new_tv function- -> [Name]- -> TcM a- -> TcM ([TcTyVar], a) -- Returned [TcTyVar] are in 1-1 correspondence- -- with the passed in [Name]-bindImplicitTKBndrsX new_tv tv_names thing_inside- = do { tkvs <- mapM new_tv tv_names- ; traceTc "bindImplicitTKBndrs" (ppr tv_names $$ ppr tkvs)- ; res <- tcExtendNameTyVarEnv (tv_names `zip` tkvs)+tcExplicitTKBndrsX :: OutputableBndrFlag flag+ => SkolemMode+ -> [LHsTyVarBndr flag GhcRn]+ -> TcM a+ -> TcM ([VarBndr TyVar flag], a)+-- Push level, capture constraints,+-- and emit an implication constraint with a ForAllSkol ic_info,+-- so that it is subject to a telescope test.+tcExplicitTKBndrsX skol_mode bndrs thing_inside+ = do { (tclvl, wanted, (skol_tvs, res))+ <- pushLevelAndCaptureConstraints $+ bindExplicitTKBndrsX skol_mode bndrs $ thing_inside- ; return (tkvs, res) } -newImplicitTyVarQ :: (Name -> TcM TcTyVar) -> Name -> TcM TcTyVar--- Behave like new_tv, except that if the tyvar is in scope, use it-newImplicitTyVarQ new_tv name- = do { mb_tv <- tcLookupLcl_maybe name- ; case mb_tv of- Just (ATyVar _ tv) -> return tv- _ -> new_tv name }--newFlexiKindedTyVar :: (Name -> Kind -> TcM TyVar) -> Name -> TcM TyVar-newFlexiKindedTyVar new_tv name- = do { kind <- newMetaKindVar- ; new_tv name kind }--newFlexiKindedSkolemTyVar :: Name -> TcM TyVar-newFlexiKindedSkolemTyVar = newFlexiKindedTyVar newSkolemTyVar--newFlexiKindedTyVarTyVar :: Name -> TcM TyVar-newFlexiKindedTyVarTyVar = newFlexiKindedTyVar newTyVarTyVar--cloneFlexiKindedTyVarTyVar :: Name -> TcM TyVar-cloneFlexiKindedTyVarTyVar = newFlexiKindedTyVar cloneTyVarTyVar- -- See Note [Cloning for tyvar binders]------------------------------------------- Explicit binders---------------------------------------+ ; let skol_info = ForAllSkol (fsep (map ppr bndrs))+ -- Notice that we use ForAllSkol here, ignoring the enclosing+ -- skol_info unlike tc_implicit_tk_bndrs, because the bad-telescope+ -- test applies only to ForAllSkol+ ; emitResidualTvConstraint skol_info (binderVars skol_tvs) tclvl wanted --- | Skolemise the 'HsTyVarBndr's in an 'LHsForAllTelescope.-bindExplicitTKTele_Skol_M- :: TcTyMode- -> HsForAllTelescope GhcRn- -> TcM a- -> TcM ([TcTyVarBinder], a)-bindExplicitTKTele_Skol_M mode tele thing_inside = case tele of- HsForAllVis { hsf_vis_bndrs = bndrs }- -> do { (req_tv_bndrs, thing) <- bindExplicitTKBndrs_Skol_M mode bndrs thing_inside- -- req_tv_bndrs :: [VarBndr TyVar ()],- -- but we want [VarBndr TyVar ArgFlag]- ; return (tyVarReqToBinders req_tv_bndrs, thing) }- HsForAllInvis { hsf_invis_bndrs = bndrs }- -> do { (inv_tv_bndrs, thing) <- bindExplicitTKBndrs_Skol_M mode bndrs thing_inside- -- inv_tv_bndrs :: [VarBndr TyVar Specificity],- -- but we want [VarBndr TyVar ArgFlag]- ; return (tyVarSpecToBinders inv_tv_bndrs, thing) }+ ; return (skol_tvs, res) } +----------------+-- | Skolemise the 'HsTyVarBndr's in an 'HsForAllTelescope' with the supplied+-- 'TcTyMode'. bindExplicitTKBndrs_Skol, bindExplicitTKBndrs_Tv :: (OutputableBndrFlag flag) => [LHsTyVarBndr flag GhcRn] -> TcM a -> TcM ([VarBndr TyVar flag], a) -bindExplicitTKBndrs_Skol_M, bindExplicitTKBndrs_Tv_M- :: (OutputableBndrFlag flag)- => TcTyMode- -> [LHsTyVarBndr flag GhcRn]- -> TcM a- -> TcM ([VarBndr TyVar flag], a)--bindExplicitTKBndrs_Skol = bindExplicitTKBndrsX (tcHsTyVarBndr (mkMode KindLevel) newSkolemTyVar)-bindExplicitTKBndrs_Skol_M mode = bindExplicitTKBndrsX (tcHsTyVarBndr (kindLevel mode) newSkolemTyVar)-bindExplicitTKBndrs_Tv = bindExplicitTKBndrsX (tcHsTyVarBndr (mkMode KindLevel) cloneTyVarTyVar)-bindExplicitTKBndrs_Tv_M mode = bindExplicitTKBndrsX (tcHsTyVarBndr (kindLevel mode) cloneTyVarTyVar)- -- newSkolemTyVar: see Note [Non-cloning for tyvar binders]- -- cloneTyVarTyVar: see Note [Cloning for tyvar binders]+bindExplicitTKBndrs_Skol = bindExplicitTKBndrsX (smVanilla { sm_clone = False })+bindExplicitTKBndrs_Tv = bindExplicitTKBndrsX (smVanilla { sm_clone = True, sm_tvtv = True })+ -- sm_clone: see Note [Cloning for type variable binders] bindExplicitTKBndrs_Q_Skol, bindExplicitTKBndrs_Q_Tv :: ContextKind -> [LHsTyVarBndr () GhcRn] -> TcM a -> TcM ([TcTyVar], a)--bindExplicitTKBndrs_Q_Skol ctxt_kind = bindExplicitTKBndrsX_Q (tcHsQTyVarBndr ctxt_kind newSkolemTyVar)-bindExplicitTKBndrs_Q_Tv ctxt_kind = bindExplicitTKBndrsX_Q (tcHsQTyVarBndr ctxt_kind newTyVarTyVar)- -- See Note [Non-cloning for tyvar binders]+-- These do not clone: see Note [Cloning for type variable binders]+bindExplicitTKBndrs_Q_Skol ctxt_kind hs_bndrs thing_inside+ = liftFstM binderVars $+ bindExplicitTKBndrsX (smVanilla { sm_clone = False, sm_parent = True+ , sm_kind = ctxt_kind })+ hs_bndrs thing_inside+ -- sm_clone=False: see Note [Cloning for type variable binders] -bindExplicitTKBndrsX_Q- :: (HsTyVarBndr () GhcRn -> TcM TcTyVar)- -> [LHsTyVarBndr () GhcRn]- -> TcM a- -> TcM ([TcTyVar], a) -- Returned [TcTyVar] are in 1-1 correspondence- -- with the passed-in [LHsTyVarBndr]-bindExplicitTKBndrsX_Q tc_tv hs_tvs thing_inside- = do { (tv_bndrs,res) <- bindExplicitTKBndrsX tc_tv hs_tvs thing_inside- ; return (binderVars tv_bndrs,res) }+bindExplicitTKBndrs_Q_Tv ctxt_kind hs_bndrs thing_inside+ = liftFstM binderVars $+ bindExplicitTKBndrsX (smVanilla { sm_clone = False, sm_parent = True+ , sm_tvtv = True, sm_kind = ctxt_kind })+ hs_bndrs thing_inside+ -- sm_clone=False: see Note [Cloning for type variable binders] bindExplicitTKBndrsX :: (OutputableBndrFlag flag)- => (HsTyVarBndr flag GhcRn -> TcM TyVar)+ => SkolemMode -> [LHsTyVarBndr flag GhcRn] -> TcM a -> TcM ([VarBndr TyVar flag], a) -- Returned [TcTyVar] are in 1-1 correspondence -- with the passed-in [LHsTyVarBndr]-bindExplicitTKBndrsX tc_tv hs_tvs thing_inside- = do { traceTc "bindExplicTKBndrs" (ppr hs_tvs)+bindExplicitTKBndrsX skol_mode@(SM { sm_parent = check_parent, sm_kind = ctxt_kind+ , sm_holes = hole_info })+ hs_tvs thing_inside+ = do { traceTc "bindExplicitTKBndrs" (ppr hs_tvs) ; go hs_tvs } where+ tc_ki_mode = TcTyMode { mode_tyki = KindLevel, mode_holes = hole_info }+ -- Inherit the HoleInfo from the context+ go [] = do { res <- thing_inside ; return ([], res) } go (L _ hs_tv : hs_tvs)- = do { tv <- tc_tv hs_tv+ = do { lcl_env <- getLclTypeEnv+ ; tv <- tc_hs_bndr lcl_env hs_tv -- Extend the environment as we go, in case a binder -- is mentioned in the kind of a later binder -- e.g. forall k (a::k). blah -- NB: tv's Name may differ from hs_tv's- -- See GHC.Tc.Utils.TcMType Note [Cloning for tyvar binders]+ -- See Note [Cloning for type variable binders] ; (tvs,res) <- tcExtendNameTyVarEnv [(hsTyVarName hs_tv, tv)] $ go hs_tvs ; return (Bndr tv (hsTyVarBndrFlag hs_tv):tvs, res) } -------------------tcHsTyVarBndr :: TcTyMode -> (Name -> Kind -> TcM TyVar)- -> HsTyVarBndr flag GhcRn -> TcM TcTyVar-tcHsTyVarBndr _ new_tv (UserTyVar _ _ (L _ tv_nm))- = do { kind <- newMetaKindVar- ; new_tv tv_nm kind }-tcHsTyVarBndr mode new_tv (KindedTyVar _ _ (L _ tv_nm) lhs_kind)- = do { kind <- tc_lhs_kind_sig mode (TyVarBndrKindCtxt tv_nm) lhs_kind- ; new_tv tv_nm kind } -------------------tcHsQTyVarBndr :: ContextKind- -> (Name -> Kind -> TcM TyVar)- -> HsTyVarBndr () GhcRn -> TcM TcTyVar--- Just like tcHsTyVarBndr, but also--- - uses the in-scope TyVar from class, if it exists--- - takes a ContextKind to use for the no-sig case-tcHsQTyVarBndr ctxt_kind new_tv (UserTyVar _ _ (L _ tv_nm))- = do { mb_tv <- tcLookupLcl_maybe tv_nm- ; case mb_tv of- Just (ATyVar _ tv) -> return tv- _ -> do { kind <- newExpectedKind ctxt_kind- ; new_tv tv_nm kind } }+ tc_hs_bndr lcl_env (UserTyVar _ _ (L _ name))+ | check_parent+ , Just (ATyVar _ tv) <- lookupNameEnv lcl_env name+ = return tv+ | otherwise+ = do { kind <- newExpectedKind ctxt_kind+ ; newTyVarBndr skol_mode name kind } -tcHsQTyVarBndr _ new_tv (KindedTyVar _ _ (L _ tv_nm) lhs_kind)- = do { kind <- tcLHsKindSig (TyVarBndrKindCtxt tv_nm) lhs_kind- ; mb_tv <- tcLookupLcl_maybe tv_nm- ; case mb_tv of- Just (ATyVar _ tv)- -> do { discardResult $ unifyKind (Just (ppr tv_nm))- kind (tyVarKind tv)- -- This unify rejects:- -- class C (m :: * -> *) where- -- type F (m :: *) = ...- ; return tv }+ tc_hs_bndr lcl_env (KindedTyVar _ _ (L _ name) lhs_kind)+ | check_parent+ , Just (ATyVar _ tv) <- lookupNameEnv lcl_env name+ = do { kind <- tc_lhs_kind_sig tc_ki_mode (TyVarBndrKindCtxt name) lhs_kind+ ; discardResult $+ unifyKind (Just (ppr name)) kind (tyVarKind tv)+ -- This unify rejects:+ -- class C (m :: * -> *) where+ -- type F (m :: *) = ...+ ; return tv } - _ -> new_tv tv_nm kind }+ | otherwise+ = do { kind <- tc_lhs_kind_sig tc_ki_mode (TyVarBndrKindCtxt name) lhs_kind+ ; newTyVarBndr skol_mode name kind } +newTyVarBndr :: SkolemMode -> Name -> Kind -> TcM TcTyVar+newTyVarBndr (SM { sm_clone = clone, sm_tvtv = tvtv }) name kind+ = do { name <- case clone of+ True -> do { uniq <- newUnique+ ; return (setNameUnique name uniq) }+ False -> return name+ ; details <- case tvtv of+ True -> newMetaDetails TyVarTv+ False -> do { lvl <- getTcLevel+ ; return (SkolemTv lvl False) }+ ; return (mkTcTyVar name kind details) }+ --------------------------------------+-- Implicit tyvar binders+--------------------------------------++tcImplicitTKBndrsX :: SkolemMode -> SkolemInfo+ -> [Name]+ -> TcM a+ -> TcM ([TcTyVar], a)+-- The workhorse:+-- push level, capture constraints,+-- and emit an implication constraint with a ForAllSkol ic_info,+-- so that it is subject to a telescope test.+tcImplicitTKBndrsX skol_mode skol_info bndrs thing_inside+ = do { (tclvl, wanted, (skol_tvs, res))+ <- pushLevelAndCaptureConstraints $+ bindImplicitTKBndrsX skol_mode bndrs $+ thing_inside++ ; emitResidualTvConstraint skol_info skol_tvs tclvl wanted++ ; return (skol_tvs, res) }++------------------+bindImplicitTKBndrs_Skol, bindImplicitTKBndrs_Tv,+ bindImplicitTKBndrs_Q_Skol, bindImplicitTKBndrs_Q_Tv+ :: [Name] -> TcM a -> TcM ([TcTyVar], a)+bindImplicitTKBndrs_Skol = bindImplicitTKBndrsX (smVanilla { sm_clone = True })+bindImplicitTKBndrs_Tv = bindImplicitTKBndrsX (smVanilla { sm_clone = True, sm_tvtv = True })+bindImplicitTKBndrs_Q_Skol = bindImplicitTKBndrsX (smVanilla { sm_clone = False, sm_parent = True })+bindImplicitTKBndrs_Q_Tv = bindImplicitTKBndrsX (smVanilla { sm_clone = False, sm_parent = True, sm_tvtv = True })++bindImplicitTKBndrsX+ :: SkolemMode+ -> [Name]+ -> TcM a+ -> TcM ([TcTyVar], a) -- Returned [TcTyVar] are in 1-1 correspondence+ -- with the passed in [Name]+bindImplicitTKBndrsX skol_mode@(SM { sm_parent = check_parent, sm_kind = ctxt_kind })+ tv_names thing_inside+ = do { lcl_env <- getLclTypeEnv+ ; tkvs <- mapM (new_tv lcl_env) tv_names+ ; traceTc "bindImplicitTKBndrsX" (ppr tv_names $$ ppr tkvs)+ ; res <- tcExtendNameTyVarEnv (tv_names `zip` tkvs)+ thing_inside+ ; return (tkvs, res) }+ where+ new_tv lcl_env name+ | check_parent+ , Just (ATyVar _ tv) <- lookupNameEnv lcl_env name+ = return tv+ | otherwise+ = do { kind <- newExpectedKind ctxt_kind+ ; newTyVarBndr skol_mode name kind }++--------------------------------------+-- SkolemMode+--------------------------------------++-- | 'SkolemMode' decribes how to typecheck an explicit ('HsTyVarBndr') or+-- implicit ('Name') binder in a type. It is just a record of flags+-- that describe what sort of 'TcTyVar' to create.+data SkolemMode+ = SM { sm_parent :: Bool -- True <=> check the in-scope parent type variable+ -- Used only for asssociated types++ , sm_clone :: Bool -- True <=> fresh unique+ -- See Note [Cloning for type variable binders]++ , sm_tvtv :: Bool -- True <=> use a TyVarTv, rather than SkolemTv+ -- Why? See Note [Inferring kinds for type declarations]+ -- in GHC.Tc.TyCl, and (in this module)+ -- Note [Checking partial type signatures]++ , sm_kind :: ContextKind -- Use this for the kind of any new binders++ , sm_holes :: HoleInfo -- What to do for wildcards in the kind+ }++smVanilla :: SkolemMode+smVanilla = SM { sm_clone = panic "sm_clone" -- We always override this+ , sm_parent = False+ , sm_tvtv = False+ , sm_kind = AnyKind+ , sm_holes = Nothing }++{- Note [Cloning for type variable binders]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Sometimes we must clone the Name of a type variable binder (written in+the source program); and sometimes we must not. This is controlled by+the sm_clone field of SkolemMode.++In some cases it doesn't matter whether or not we clone. Perhaps+it'd be better to use MustClone/MayClone/MustNotClone.++When we /must not/ clone+* In the binders of a type signature (tcOuterTKBndrs)+ f :: forall a{27}. blah+ f = rhs+ Then 'a' scopes over 'rhs'. When we kind-check the signature (tcHsSigType),+ we must get the type (forall a{27}. blah) for the Id f, because+ we bring that type variable into scope when we typecheck 'rhs'.++* In the binders of a data family instance (bindOuterFamEqnTKBndrs)+ data instance+ forall p q. D (p,q) = D1 p | D2 q+ We kind-check the LHS in tcDataFamInstHeader, and then separately+ (in tcDataFamInstDecl) bring p,q into scope before looking at the+ the constructor decls.++* bindExplicitTKBndrs_Q_Tv/bindImplicitTKBndrs_Q_Tv do not clone+ We take advantage of this in kcInferDeclHeader:+ all_tv_prs = mkTyVarNamePairs (scoped_kvs ++ tc_tvs)+ If we cloned, we'd need to take a bit more care here; not hard.++* bindExplicitTKBndrs_Q_Skol, bindExplicitTKBndrs_Skol, do not clone.+ There is no need, I think.++ The payoff here is that avoiding gratuitous cloning means that we can+ almost always take the fast path in swizzleTcTyConBndrs.++When we /must/ clone.+* bindOuterSigTKBndrs_Tv, bindExplicitTKBndrs_Tv do cloning++ This for a narrow and tricky reason which, alas, I couldn't find a+ simpler way round. #16221 is the poster child:++ data SameKind :: k -> k -> *+ data T a = forall k2 (b :: k2). MkT (SameKind a b) !Int++ When kind-checking T, we give (a :: kappa1). Then:++ - In kcConDecl we make a TyVarTv unification variable kappa2 for k2+ (as described in Note [Kind-checking for GADTs], even though this+ example is an existential)+ - So we get (b :: kappa2) via bindExplicitTKBndrs_Tv+ - We end up unifying kappa1 := kappa2, because of the (SameKind a b)++ Now we generalise over kappa2. But if kappa2's Name is precisely k2+ (i.e. we did not clone) we'll end up giving T the utterly final kind+ T :: forall k2. k2 -> *+ Nothing directly wrong with that but when we typecheck the data constructor+ we have k2 in scope; but then it's brought into scope /again/ when we find+ the forall k2. This is chaotic, and we end up giving it the type+ MkT :: forall k2 (a :: k2) k2 (b :: k2).+ SameKind @k2 a b -> Int -> T @{k2} a+ which is bogus -- because of the shadowing of k2, we can't+ apply T to the kind or a!++ And there no reason /not/ to clone the Name when making a unification+ variable. So that's what we do.+-}++-------------------------------------- -- Binding type/class variables in the -- kind-checking and typechecking phases --------------------------------------@@ -3161,8 +3342,8 @@ zonkAndScopedSort :: [TcTyVar] -> TcM [TcTyVar] zonkAndScopedSort spec_tkvs- = do { spec_tkvs <- mapM zonkAndSkolemise spec_tkvs- -- Use zonkAndSkolemise because a skol_tv might be a TyVarTv+ = do { spec_tkvs <- mapM zonkTcTyVarToTyVar spec_tkvs+ -- Zonk the kinds, to we can do the dependency analayis -- Do a stable topological sort, following -- Note [Ordering of implicit variables] in GHC.Rename.HsType@@ -3563,18 +3744,16 @@ , TcType ) -- Tau part -- See Note [Checking partial type signatures] tcHsPartialSigType ctxt sig_ty- | HsWC { hswc_ext = sig_wcs, hswc_body = ib_ty } <- sig_ty- , HsIB { hsib_ext = implicit_hs_tvs- , hsib_body = hs_ty } <- ib_ty- , (explicit_hs_tvs, L _ hs_ctxt, hs_tau) <- splitLHsSigmaTyInvis hs_ty- = addSigCtxt ctxt hs_ty $+ | HsWC { hswc_ext = sig_wcs, hswc_body = sig_ty } <- sig_ty+ , L _ (HsSig{sig_bndrs = hs_outer_bndrs, sig_body = body_ty}) <- sig_ty+ , (L _ hs_ctxt, hs_tau) <- splitLHsQualTy body_ty+ = addSigCtxt ctxt sig_ty $ do { mode <- mkHoleMode TypeLevel HM_Sig- ; (implicit_tvs, (explicit_tvbndrs, (wcs, wcx, theta, tau)))- <- solveEqualities "tcHsPartialSigType" $+ ; (outer_bndrs, (wcs, wcx, theta, tau))+ <- solveEqualities "tcHsPartialSigType" $ -- See Note [Failure in local type signatures]- tcNamedWildCardBinders sig_wcs $ \ wcs ->- bindImplicitTKBndrs_Tv implicit_hs_tvs $- bindExplicitTKBndrs_Tv_M mode explicit_hs_tvs $+ bindNamedWildCardBinders sig_wcs $ \ wcs ->+ bindOuterSigTKBndrs_Tv_M mode hs_outer_bndrs $ do { -- Instantiate the type-class context; but if there -- is an extra-constraints wildcard, just discard it here (theta, wcx) <- tcPartialContext mode hs_ctxt@@ -3585,11 +3764,12 @@ ; return (wcs, wcx, theta, tau) } - ; let implicit_tvbndrs = map (mkTyVarBinder SpecifiedSpec) implicit_tvs+ ; traceTc "tcHsPartialSigType 2" empty+ ; outer_tv_bndrs <- scopedSortOuter outer_bndrs+ ; traceTc "tcHsPartialSigType 3" empty -- No kind-generalization here:- ; kindGeneralizeNone (mkInvisForAllTys implicit_tvbndrs $- mkInvisForAllTys explicit_tvbndrs $+ ; kindGeneralizeNone (mkInvisForAllTys outer_tv_bndrs $ mkPhiTy theta $ tau) @@ -3601,16 +3781,17 @@ -- Zonk, so that any nested foralls can "see" their occurrences -- See Note [Checking partial type signatures], and in particular -- Note [Levels for wildcards]- ; implicit_tvbndrs <- mapM zonkInvisTVBinder implicit_tvbndrs- ; explicit_tvbndrs <- mapM zonkInvisTVBinder explicit_tvbndrs- ; theta <- mapM zonkTcType theta- ; tau <- zonkTcType tau+ ; outer_tv_bndrs <- mapM zonkInvisTVBinder outer_tv_bndrs+ ; theta <- mapM zonkTcType theta+ ; tau <- zonkTcType tau -- We return a proper (Name,InvisTVBinder) environment, to be sure that -- we bring the right name into scope in the function body. -- Test case: partial-sigs/should_compile/LocalDefinitionBug- ; let tv_prs = (implicit_hs_tvs `zip` implicit_tvbndrs)- ++ (hsLTyVarNames explicit_hs_tvs `zip` explicit_tvbndrs)+ ; let outer_bndr_names :: [Name]+ outer_bndr_names = hsOuterTyVarNames hs_outer_bndrs+ tv_prs :: [(Name,InvisTVBinder)]+ tv_prs = outer_bndr_names `zip` outer_tv_bndrs -- NB: checkValidType on the final inferred type will be -- done later by checkInferredPolyId. We can't do it@@ -3656,7 +3837,7 @@ They are typechecked as a recursive group, with monomorphic types, so 'a' and 'b' will get unified together. Very like kind inference for mutually recursive data types (sans CUSKs or SAKS); see- Note [Cloning for tyvar binders] in GHC.Tc.Gen.HsType+ Note [Cloning for type variable binders] * In GHC.Tc.Gen.Sig.tcUserSigType we return a PartialSig, which (unlike the companion CompleteSig) contains the original, as-yet-unchecked@@ -3784,7 +3965,7 @@ solveEqualities "tcHsPatSigType" $ -- See Note [Failure in local type signatures] -- and c.f #16033- tcNamedWildCardBinders sig_wcs $ \ wcs ->+ bindNamedWildCardBinders sig_wcs $ \ wcs -> tcExtendNameTyVarEnv sig_tkv_prs $ do { ek <- newOpenTypeKind ; sig_ty <- tc_lhs_type mode hs_ty ek@@ -3890,7 +4071,7 @@ tcLHsKindSig :: UserTypeCtxt -> LHsKind GhcRn -> TcM Kind tcLHsKindSig ctxt hs_kind- = tc_lhs_kind_sig (mkMode KindLevel) ctxt hs_kind+ = tc_lhs_kind_sig kindLevelMode ctxt hs_kind tc_lhs_kind_sig :: TcTyMode -> UserTypeCtxt -> LHsKind GhcRn -> TcM Kind tc_lhs_kind_sig mode ctxt hs_kind@@ -3927,7 +4108,11 @@ NoDataKindsTC -> text "perhaps you intended to use DataKinds" NoDataKindsDC -> text "perhaps you intended to use DataKinds" PatSynPE -> text "pattern synonyms cannot be promoted"- _ -> text "it is defined and used in the same recursive group"+ RecDataConPE -> same_rec_group_msg+ ClassPE -> same_rec_group_msg+ TyConPE -> same_rec_group_msg++ same_rec_group_msg = text "it is defined and used in the same recursive group" {- ************************************************************************
compiler/GHC/Tc/Gen/Pat.hs view
@@ -838,6 +838,15 @@ RIP GADT refinement: refinements have been replaced by the use of explicit equality constraints that are used in conjunction with implication constraints to express the local scope of GADT refinements.++Note [Freshen existentials]+~~~~~~~~~~~~~~~~~~~~~~~~~~~+It is essential that these existentials are freshened.+Otherwise, if we have something like+ case (a :: Ex, b :: Ex) of (MkEx ..., MkEx ...) -> ...+we'll give both unpacked existential variables the+same name, leading to shadowing.+ -} -- Running example:@@ -888,6 +897,7 @@ ; (tenv, ex_tvs') <- tcInstSuperSkolTyVarsX tenv ex_tvs -- Get location from monad, not from ex_tvs+ -- This freshens: See Note [Freshen existentials] ; let -- pat_ty' = mkTyConApp tycon ctxt_res_tys -- pat_ty' is type of the actual constructor application@@ -974,6 +984,8 @@ ; let all_arg_tys = ty : prov_theta ++ (map scaledThing arg_tys) ; checkExistentials ex_tvs all_arg_tys penv ; (tenv, ex_tvs') <- tcInstSuperSkolTyVarsX subst ex_tvs+ -- This freshens: Note [Freshen existentials]+ ; let ty' = substTy tenv ty arg_tys' = substScaledTys tenv arg_tys pat_mult = scaledMult pat_ty
compiler/GHC/Tc/Gen/Sig.hs view
@@ -32,6 +32,7 @@ import GHC.Tc.Types import GHC.Tc.Solver( pushLevelAndSolveEqualitiesX, reportUnsolvedEqualities ) import GHC.Tc.Utils.Monad+import GHC.Tc.Utils.Zonk import GHC.Tc.Types.Origin import GHC.Tc.Utils.TcType import GHC.Tc.Utils.TcMType@@ -104,21 +105,8 @@ unification variables is correct because we are in tcMonoBinds. -Note [Scoped tyvars]-~~~~~~~~~~~~~~~~~~~~-The -XScopedTypeVariables flag brings lexically-scoped type variables-into scope for any explicitly forall-quantified type variables:- f :: forall a. a -> a- f x = e-Then 'a' is in scope inside 'e'.--However, we do *not* support this- - For pattern bindings e.g- f :: forall a. a->a- (f,g) = e- Note [Binding scoped type variables]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The type variables *brought into lexical scope* by a type signature may be a subset of the *quantified type variables* of the signatures, for two reasons:@@ -264,13 +252,17 @@ , sig_loc = getSrcSpan id } isCompleteHsSig :: LHsSigWcType GhcRn -> Bool--- ^ If there are no wildcards, return a LHsSigType-isCompleteHsSig (HsWC { hswc_ext = wcs- , hswc_body = HsIB { hsib_body = hs_ty } })- = null wcs && no_anon_wc hs_ty+-- ^ If there are no wildcards, return a LHsSigWcType+isCompleteHsSig (HsWC { hswc_ext = wcs, hswc_body = hs_sig_ty })+ = null wcs && no_anon_wc_sig_ty hs_sig_ty -no_anon_wc :: LHsType GhcRn -> Bool-no_anon_wc lty = go lty+no_anon_wc_sig_ty :: LHsSigType GhcRn -> Bool+no_anon_wc_sig_ty (L _ (HsSig{sig_bndrs = outer_bndrs, sig_body = body}))+ = all no_anon_wc_tvb (hsOuterExplicitBndrs outer_bndrs)+ && no_anon_wc_ty body++no_anon_wc_ty :: LHsType GhcRn -> Bool+no_anon_wc_ty lty = go lty where go (L _ ty) = case ty of HsWildCardTy _ -> False@@ -305,12 +297,14 @@ no_anon_wc_tele :: HsForAllTelescope GhcRn -> Bool no_anon_wc_tele tele = case tele of- HsForAllVis { hsf_vis_bndrs = ltvs } -> all (go . unLoc) ltvs- HsForAllInvis { hsf_invis_bndrs = ltvs } -> all (go . unLoc) ltvs- where- go (UserTyVar _ _ _) = True- go (KindedTyVar _ _ _ ki) = no_anon_wc ki+ HsForAllVis { hsf_vis_bndrs = ltvs } -> all no_anon_wc_tvb ltvs+ HsForAllInvis { hsf_invis_bndrs = ltvs } -> all no_anon_wc_tvb ltvs +no_anon_wc_tvb :: LHsTyVarBndr flag GhcRn -> Bool+no_anon_wc_tvb (L _ tvb) = case tvb of+ UserTyVar _ _ _ -> True+ KindedTyVar _ _ _ ki -> no_anon_wc_ty ki+ {- Note [Fail eagerly on bad signatures] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If a type signature is wrong, fail immediately:@@ -378,17 +372,17 @@ tcPatSynSig :: Name -> LHsSigType GhcRn -> TcM TcPatSynInfo -- See Note [Pattern synonym signatures] -- See Note [Recipe for checking a signature] in GHC.Tc.Gen.HsType-tcPatSynSig name sig_ty- | HsIB { hsib_ext = implicit_hs_tvs- , hsib_body = hs_ty } <- sig_ty- , (univ_hs_tvbndrs, hs_req, hs_ty1) <- splitLHsSigmaTyInvis hs_ty- , (ex_hs_tvbndrs, hs_prov, hs_body_ty) <- splitLHsSigmaTyInvis hs_ty1- = do { traceTc "tcPatSynSig 1" (ppr sig_ty)- ; (tclvl, wanted, (implicit_tvs, (univ_tvbndrs, (ex_tvbndrs, (req, prov, body_ty)))))- <- pushLevelAndSolveEqualitiesX "tcPatSynSig" $- bindImplicitTKBndrs_Skol implicit_hs_tvs $- bindExplicitTKBndrs_Skol univ_hs_tvbndrs $- bindExplicitTKBndrs_Skol ex_hs_tvbndrs $+tcPatSynSig name sig_ty@(L _ (HsSig{sig_bndrs = hs_outer_bndrs, sig_body = hs_ty}))+ | (hs_req, hs_ty1) <- splitLHsQualTy hs_ty+ , (ex_hs_tvbndrs, hs_prov, hs_body_ty) <- splitLHsSigmaTyInvis hs_ty1+ = do { traceTc "tcPatSynSig 1" (ppr sig_ty)++ ; let skol_info = DataConSkol name+ ; (tclvl, wanted, (outer_bndrs, (ex_bndrs, (req, prov, body_ty))))+ <- pushLevelAndSolveEqualitiesX "tcPatSynSig" $+ -- See Note [solveEqualities in tcPatSynSig]+ tcOuterTKBndrs skol_info hs_outer_bndrs $+ tcExplicitTKBndrs ex_hs_tvbndrs $ do { req <- tcHsContext hs_req ; prov <- tcHsContext hs_prov ; body_ty <- tcHsOpenType hs_body_ty@@ -396,32 +390,37 @@ -- e.g. pattern Zero <- 0# (#12094) ; return (req, prov, body_ty) } + ; let implicit_tvs :: [TcTyVar]+ univ_bndrs :: [TcInvisTVBinder]+ (implicit_tvs, univ_bndrs) = case outer_bndrs of+ HsOuterImplicit{hso_ximplicit = implicit_tvs} -> (implicit_tvs, [])+ HsOuterExplicit{hso_xexplicit = univ_bndrs} -> ([], univ_bndrs)+ ; implicit_tvs <- zonkAndScopedSort implicit_tvs- ; let ungen_patsyn_ty = build_patsyn_type [] implicit_tvs univ_tvbndrs- req ex_tvbndrs prov body_ty+ ; let implicit_bndrs = mkTyVarBinders SpecifiedSpec implicit_tvs -- Kind generalisation- ; kvs <- kindGeneralizeAll ungen_patsyn_ty+ ; let ungen_patsyn_ty = build_patsyn_type implicit_bndrs univ_bndrs+ req ex_bndrs prov body_ty ; traceTc "tcPatSynSig" (ppr ungen_patsyn_ty)-- ; let skol_tvs = kvs ++ implicit_tvs ++ binderVars (univ_tvbndrs ++ ex_tvbndrs)- skol_info = DataConSkol name- ; reportUnsolvedEqualities skol_info skol_tvs tclvl wanted+ ; kvs <- kindGeneralizeAll ungen_patsyn_ty+ ; reportUnsolvedEqualities skol_info kvs tclvl wanted -- See Note [Report unsolved equalities in tcPatSynSig] -- These are /signatures/ so we zonk to squeeze out any kind -- unification variables. Do this after kindGeneralizeAll which may -- default kind variables to *.- ; implicit_tvs <- mapM zonkTcTyVarToTyVar implicit_tvs- ; univ_tvbndrs <- mapM zonkTyCoVarKindBinder univ_tvbndrs- ; ex_tvbndrs <- mapM zonkTyCoVarKindBinder ex_tvbndrs- ; req <- zonkTcTypes req- ; prov <- zonkTcTypes prov- ; body_ty <- zonkTcType body_ty+ ; (ze, kv_bndrs) <- zonkTyVarBinders (mkTyVarBinders InferredSpec kvs)+ ; (ze, implicit_bndrs) <- zonkTyVarBindersX ze implicit_bndrs+ ; (ze, univ_bndrs) <- zonkTyVarBindersX ze univ_bndrs+ ; (ze, ex_bndrs) <- zonkTyVarBindersX ze ex_bndrs+ ; req <- zonkTcTypesToTypesX ze req+ ; prov <- zonkTcTypesToTypesX ze prov+ ; body_ty <- zonkTcTypeToTypeX ze body_ty -- Now do validity checking ; checkValidType ctxt $- build_patsyn_type kvs implicit_tvs univ_tvbndrs req ex_tvbndrs prov body_ty+ build_patsyn_type implicit_bndrs univ_bndrs req ex_bndrs prov body_ty -- arguments become the types of binders. We thus cannot allow -- levity polymorphism here@@ -429,27 +428,25 @@ ; mapM_ (checkForLevPoly empty . scaledThing) arg_tys ; traceTc "tcTySig }" $- vcat [ text "implicit_tvs" <+> ppr_tvs implicit_tvs- , text "kvs" <+> ppr_tvs kvs- , text "univ_tvs" <+> ppr_tvs (binderVars univ_tvbndrs)+ vcat [ text "kvs" <+> ppr_tvs (binderVars kv_bndrs)+ , text "implicit_tvs" <+> ppr_tvs (binderVars implicit_bndrs)+ , text "univ_tvs" <+> ppr_tvs (binderVars univ_bndrs) , text "req" <+> ppr req- , text "ex_tvs" <+> ppr_tvs (binderVars ex_tvbndrs)+ , text "ex_tvs" <+> ppr_tvs (binderVars ex_bndrs) , text "prov" <+> ppr prov , text "body_ty" <+> ppr body_ty ] ; return (TPSI { patsig_name = name- , patsig_implicit_bndrs = mkTyVarBinders InferredSpec kvs ++- mkTyVarBinders SpecifiedSpec implicit_tvs- , patsig_univ_bndrs = univ_tvbndrs+ , patsig_implicit_bndrs = kv_bndrs ++ implicit_bndrs+ , patsig_univ_bndrs = univ_bndrs , patsig_req = req- , patsig_ex_bndrs = ex_tvbndrs+ , patsig_ex_bndrs = ex_bndrs , patsig_prov = prov , patsig_body_ty = body_ty }) } where ctxt = PatSynCtxt name - build_patsyn_type kvs imp univ_bndrs req ex_bndrs prov body- = mkInfForAllTys kvs $- mkSpecForAllTys imp $+ build_patsyn_type implicit_bndrs univ_bndrs req ex_bndrs prov body+ = mkInvisForAllTys implicit_bndrs $ mkInvisForAllTys univ_bndrs $ mkPhiTy req $ mkInvisForAllTys ex_bndrs $
compiler/GHC/Tc/Gen/Splice.hs view
@@ -932,7 +932,7 @@ -- run plugins ; hsc_env <- getTopEnv- ; expr' <- withPlugins (hsc_dflags hsc_env) spliceRunAction expr+ ; expr' <- withPlugins hsc_env spliceRunAction expr -- Desugar ; ds_expr <- initDsTc (dsLExpr expr')@@ -2148,12 +2148,12 @@ -- Arg of reify_for_all is always ForAllTy or a predicate FunTy reify_for_all argf ty | isVisibleArgFlag argf- = do let (req_bndrs, phi) = tcSplitForAllTysReq ty+ = do let (req_bndrs, phi) = tcSplitForAllReqTVBinders ty tvbndrs' <- reifyTyVarBndrs req_bndrs phi' <- reifyType phi pure $ TH.ForallVisT tvbndrs' phi' | otherwise- = do let (inv_bndrs, phi) = tcSplitForAllTysInvis ty+ = do let (inv_bndrs, phi) = tcSplitForAllInvisTVBinders ty tvbndrs' <- reifyTyVarBndrs inv_bndrs let (cxt, tau) = tcSplitPhiTy phi cxt' <- reifyCxt cxt
compiler/GHC/Tc/Instance/Typeable.hs view
@@ -407,7 +407,7 @@ -> TypeableTyCon -> KindRepM (LHsBinds GhcTc) mkTyConRepBinds stuff todo (TypeableTyCon {..}) = do -- Make a KindRep- let (bndrs, kind) = splitForAllVarBndrs (tyConKind tycon)+ let (bndrs, kind) = splitForAllTyCoVarBinders (tyConKind tycon) liftTc $ traceTc "mkTyConKindRepBinds" (ppr tycon $$ ppr (tyConKind tycon) $$ ppr kind) let ctx = mkDeBruijnContext (map binderVar bndrs)
compiler/GHC/Tc/Module.hs view
@@ -296,11 +296,7 @@ tcRnSrcDecls explicit_mod_hdr local_decls export_ies ; whenM (goptM Opt_DoCoreLinting) $- do { let (warns, errs) = lintGblEnv (hsc_dflags hsc_env) tcg_env- ; mapBagM_ (addWarn NoReason) warns- ; mapBagM_ addErr errs- ; failIfErrsM } -- if we have a lint error, we're only- -- going to get in deeper trouble by proceeding+ lintGblEnv (hsc_dflags hsc_env) tcg_env ; setGblEnv tcg_env $ do { -- Process the export list@@ -330,7 +326,7 @@ reportUnusedNames tcg_env hsc_src ; -- add extra source files to tcg_dependent_files addDependentFiles src_files- ; tcg_env <- runTypecheckerPlugin mod_sum hsc_env tcg_env+ ; tcg_env <- runTypecheckerPlugin mod_sum tcg_env ; -- Dump output and return tcDump tcg_env ; return tcg_env }@@ -2474,14 +2470,14 @@ let ghciM = nlHsAppTy (nlHsTyVar ghciTy) (nlHsTyVar a_tv) ioM = nlHsAppTy (nlHsTyVar ioTyConName) (nlHsTyVar a_tv) - step_ty = noLoc $ HsForAllTy- { hst_tele = mkHsForAllInvisTele- [noLoc $ UserTyVar noExtField SpecifiedSpec (noLoc a_tv)]- , hst_xforall = noExtField- , hst_body = nlHsFunTy ghciM ioM }+ step_ty :: LHsSigType GhcRn+ step_ty = noLoc $ HsSig+ { sig_bndrs = HsOuterImplicit{hso_ximplicit = [a_tv]}+ , sig_ext = noExtField+ , sig_body = nlHsFunTy ghciM ioM } stepTy :: LHsSigWcType GhcRn- stepTy = mkEmptyWildCardBndrs (mkEmptyImplicitBndrs step_ty)+ stepTy = mkEmptyWildCardBndrs step_ty return (noLoc $ ExprWithTySig noExtField (nlHsVar ghciStepIoMName) stepTy) @@ -2614,7 +2610,7 @@ ; traceTc "tcRnType" (vcat [ppr wcs, ppr rn_type]) ; (_tclvl, wanted, (ty, kind)) <- pushLevelAndSolveEqualitiesX "tcRnType" $- tcNamedWildCardBinders wcs $ \ wcs' ->+ bindNamedWildCardBinders wcs $ \ wcs' -> do { mapM_ emitNamedTypeHole wcs' ; tcInferLHsTypeUnsaturated rn_type } @@ -2629,12 +2625,13 @@ -- Do validity checking on type ; checkValidType (GhciCtxt True) ty - ; ty' <- if normalise- then do { fam_envs <- tcGetFamInstEnvs- ; let (_, ty')- = normaliseType fam_envs Nominal ty- ; return ty' }- else return ty ;+ -- Optionally (:k vs :k!) normalise the type. Does two things:+ -- normaliseType: expand type-family applications+ -- expandTypeSynonyms: expand type synonyms (#18828)+ ; fam_envs <- tcGetFamInstEnvs+ ; let ty' | normalise = expandTypeSynonyms $ snd $+ normaliseType fam_envs Nominal ty+ | otherwise = ty ; return (ty', mkInfForAllTys kvs (tcTypeKind ty')) } @@ -3037,10 +3034,10 @@ withTcPlugins :: HscEnv -> TcM a -> TcM a withTcPlugins hsc_env m =- do let plugins = getTcPlugins (hsc_dflags hsc_env)- case plugins of- [] -> m -- Common fast case- _ -> do ev_binds_var <- newTcEvBinds+ case getTcPlugins hsc_env of+ [] -> m -- Common fast case+ plugins -> do+ ev_binds_var <- newTcEvBinds (solvers,stops) <- unzip `fmap` mapM (startPlugin ev_binds_var) plugins -- This ensures that tcPluginStop is called even if a type -- error occurs during compilation (Fix of #10078)@@ -3055,13 +3052,13 @@ do s <- runTcPluginM start ev_binds_var return (solve s, stop s) -getTcPlugins :: DynFlags -> [GHC.Tc.Utils.Monad.TcPlugin]-getTcPlugins dflags = catMaybes $ mapPlugins dflags (\p args -> tcPlugin p args)+getTcPlugins :: HscEnv -> [GHC.Tc.Utils.Monad.TcPlugin]+getTcPlugins hsc_env = catMaybes $ mapPlugins hsc_env (\p args -> tcPlugin p args) withHoleFitPlugins :: HscEnv -> TcM a -> TcM a withHoleFitPlugins hsc_env m =- case (getHfPlugins (hsc_dflags hsc_env)) of+ case getHfPlugins hsc_env of [] -> m -- Common fast case plugins -> do (plugins,stops) <- unzip `fmap` mapM startPlugin plugins -- This ensures that hfPluginStop is called even if a type@@ -3077,18 +3074,19 @@ do ref <- init return (plugin ref, stop ref) -getHfPlugins :: DynFlags -> [HoleFitPluginR]-getHfPlugins dflags =- catMaybes $ mapPlugins dflags (\p args -> holeFitPlugin p args)+getHfPlugins :: HscEnv -> [HoleFitPluginR]+getHfPlugins hsc_env =+ catMaybes $ mapPlugins hsc_env (\p args -> holeFitPlugin p args) runRenamerPlugin :: TcGblEnv -> HsGroup GhcRn -> TcM (TcGblEnv, HsGroup GhcRn) runRenamerPlugin gbl_env hs_group = do- dflags <- getDynFlags- withPlugins dflags- (\p opts (e, g) -> ( mark_plugin_unsafe dflags >> renamedResultAction p opts e g))+ hsc_env <- getTopEnv+ withPlugins hsc_env+ (\p opts (e, g) -> ( mark_plugin_unsafe (hsc_dflags hsc_env)+ >> renamedResultAction p opts e g)) (gbl_env, hs_group) @@ -3106,11 +3104,11 @@ , tcg_rn_exports tc_result, tcg_doc_hdr tc_result ) ) (tcg_rn_decls tc_result) -runTypecheckerPlugin :: ModSummary -> HscEnv -> TcGblEnv -> TcM TcGblEnv-runTypecheckerPlugin sum hsc_env gbl_env = do- let dflags = hsc_dflags hsc_env- withPlugins dflags- (\p opts env -> mark_plugin_unsafe dflags+runTypecheckerPlugin :: ModSummary -> TcGblEnv -> TcM TcGblEnv+runTypecheckerPlugin sum gbl_env = do+ hsc_env <- getTopEnv+ withPlugins hsc_env+ (\p opts env -> mark_plugin_unsafe (hsc_dflags hsc_env) >> typeCheckResultAction p opts sum env) gbl_env
compiler/GHC/Tc/Solver.hs view
@@ -18,7 +18,7 @@ simplifyTopWanteds, - promoteTyVarSet, emitFlatConstraints,+ promoteTyVarSet, simplifyAndEmitFlatConstraints, -- For Rules we need these solveWanteds, solveWantedsAndDrop,@@ -200,24 +200,29 @@ solveEqualities callsite thing_inside = do { traceTc "solveEqualities {" (text "Called from" <+> text callsite) ; (res, wanted) <- captureConstraints thing_inside- ; residual_wanted <- runTcSEqualities (solveWantedsAndDrop wanted)- ; emitFlatConstraints residual_wanted- -- emitFlatConstraints fails outright unless the only unsolved- -- constraints are soluble-looking equalities that can float out- ; traceTc "solveEqualities }" (text "Residual: " <+> ppr residual_wanted)+ ; simplifyAndEmitFlatConstraints wanted+ -- simplifyAndEmitFlatConstraints fails outright unless+ -- the only unsolved constraints are soluble-looking+ -- equalities that can float out+ ; traceTc "solveEqualities }" empty ; return res } -emitFlatConstraints :: WantedConstraints -> TcM ()+simplifyAndEmitFlatConstraints :: WantedConstraints -> TcM () -- See Note [Failure in local type signatures]-emitFlatConstraints wanted- = do { wanted <- TcM.zonkWC wanted+simplifyAndEmitFlatConstraints wanted+ = do { -- Solve and zonk to esablish the+ -- preconditions for floatKindEqualities+ wanted <- runTcSEqualities (solveWanteds wanted)+ ; wanted <- TcM.zonkWC wanted++ ; traceTc "emitFlatConstraints {" (ppr wanted) ; case floatKindEqualities wanted of- Nothing -> do { traceTc "emitFlatConstraints: failing" (ppr wanted)+ Nothing -> do { traceTc "emitFlatConstraints } failing" (ppr wanted) ; emitConstraints wanted -- So they get reported! ; failM } Just (simples, holes)- -> do { _ <- TcM.promoteTyVarSet (tyCoVarsOfCts simples)- ; traceTc "emitFlatConstraints:" $+ -> do { _ <- promoteTyVarSet (tyCoVarsOfCts simples)+ ; traceTc "emitFlatConstraints }" $ vcat [ text "simples:" <+> ppr simples , text "holes: " <+> ppr holes ] ; emitHoles holes -- Holes don't need promotion@@ -228,6 +233,12 @@ -- Return Nothing if any constraints can't be floated (captured -- by skolems), or if there is an insoluble constraint, or -- IC_Telescope telescope error+-- Precondition 1: we have tried to solve the 'wanteds', both so that+-- the ic_status field is set, and because solving can make constraints+-- more floatable.+-- Precondition 2: the 'wanteds' are zonked, since floatKindEqualities+-- is not monadic+-- See Note [floatKindEqualities vs approximateWC] floatKindEqualities wc = float_wc emptyVarSet wc where float_wc :: TcTyCoVarSet -> WantedConstraints -> Maybe (Bag Ct, Bag Hole)@@ -328,7 +339,7 @@ * buildTvImplication: build an implication for the residual, unsolved constraint -* emitFlatConstraints: try to float out every unsolved equalities+* simplifyAndEmitFlatConstraints: try to float out every unsolved equality inside that implication, in the hope that it constrains only global type variables, not the locally-quantified ones. @@ -364,6 +375,16 @@ reporting errors, we avoid that happening. See also #18062, #11506++Note [floatKindEqualities vs approximateWC]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+floatKindEqualities and approximateWC are strikingly similar to each+other, but++* floatKindEqualites tries to float /all/ equalities, and fails if+ it can't, or if any implication is insoluble.+* approximateWC just floats out any constraints+ (not just equalities) that can float; it never fails. -} @@ -1928,7 +1949,7 @@ -- See Note [Checking telescopes] in GHC.Tc.Types.Constraint checkBadTelescope (Implic { ic_info = info , ic_skols = skols })- | ForAllSkol {} <- info+ | checkTelescopeSkol info = do{ skols <- mapM TcS.zonkTyCoVarKind skols ; return (go emptyVarSet (reverse skols))} @@ -2237,6 +2258,7 @@ approximateWC :: Bool -> WantedConstraints -> Cts -- Postcondition: Wanted or Derived Cts -- See Note [ApproximateWC]+-- See Note [floatKindEqualities vs approximateWC] approximateWC float_past_equalities wc = float_wc emptyVarSet wc where
compiler/GHC/Tc/Solver/Canonical.hs view
@@ -549,7 +549,7 @@ mk_given_desc sel_id sc_pred = (swizzled_pred, swizzled_evterm) where- (sc_tvs, sc_rho) = splitForAllTys sc_pred+ (sc_tvs, sc_rho) = splitForAllTyCoVars sc_pred (sc_theta, sc_inner_pred) = splitFunTys sc_rho all_tvs = tvs `chkAppend` sc_tvs@@ -1147,8 +1147,8 @@ can_eq_nc_forall ev eq_rel s1 s2 | CtWanted { ctev_loc = loc, ctev_dest = orig_dest } <- ev = do { let free_tvs = tyCoVarsOfTypes [s1,s2]- (bndrs1, phi1) = tcSplitForAllVarBndrs s1- (bndrs2, phi2) = tcSplitForAllVarBndrs s2+ (bndrs1, phi1) = tcSplitForAllTyVarBinders s1+ (bndrs2, phi2) = tcSplitForAllTyVarBinders s2 ; if not (equalLength bndrs1 bndrs2) then do { traceTcS "Forall failure" $ vcat [ ppr s1, ppr s2, ppr bndrs1, ppr bndrs2@@ -2145,7 +2145,7 @@ | otherwise -- For some reason (occurs check, or forall) we can't unify -- We must not use it for further rewriting!- = do { traceTcS "canEqTyVar2 can't unify" (ppr tv1 $$ ppr rhs)+ = do { traceTcS "canEqTyVar2 can't unify" (ppr tv1 $$ ppr rhs $$ ppr mtvu) ; new_ev <- rewriteEqEvidence ev swapped lhs rhs rewrite_co1 rewrite_co2 ; let status | isInsolubleOccursCheck eq_rel tv1 rhs = InsolubleCIS
compiler/GHC/Tc/Solver/Flatten.hs view
@@ -1196,7 +1196,7 @@ -- We allow for-alls when, but only when, no type function -- applications inside the forall involve the bound type variables.- = do { let (bndrs, rho) = tcSplitForAllVarBndrs ty+ = do { let (bndrs, rho) = tcSplitForAllTyVarBinders ty tvs = binderVars bndrs ; (rho', co) <- setMode FM_SubstOnly $ flatten_one rho -- Substitute only under a forall
compiler/GHC/Tc/TyCl.hs view
@@ -38,6 +38,8 @@ , reportUnsolvedEqualities ) import GHC.Tc.Utils.Monad import GHC.Tc.Utils.Env+import GHC.Tc.Utils.Unify( emitResidualTvConstraint )+import GHC.Tc.Types.Constraint( emptyWC ) import GHC.Tc.Validity import GHC.Tc.Utils.Zonk import GHC.Tc.TyCl.Utils@@ -755,7 +757,9 @@ swizzleTcTyConBndrs tc_infos | all no_swizzle swizzle_prs -- This fast path happens almost all the time- -- See Note [Non-cloning for tyvar binders] in GHC.Tc.Gen.HsType+ -- See Note [Cloning for type variable binders] in GHC.Tc.Gen.HsType+ -- "Almost all the time" means not the case of mutual recursion with+ -- polymorphic kinds. = do { traceTc "Skipping swizzleTcTyConBndrs for" (ppr (map fstOf3 tc_infos)) ; return tc_infos } @@ -1560,11 +1564,9 @@ do { _ <- tcHsContext ctxt ; mapM_ (wrapLocM_ kc_sig) sigs } where- kc_sig (ClassOpSig _ _ nms op_ty) = kcClassSigType skol_info nms op_ty+ kc_sig (ClassOpSig _ _ nms op_ty) = kcClassSigType nms op_ty kc_sig _ = return () - skol_info = TyConSkol ClassFlavour name- kcTyClDecl (FamDecl _ (FamilyDecl { fdInfo = fd_info })) fam_tc -- closed type families look at their equations, but other families don't -- do anything here@@ -1636,8 +1638,8 @@ } kcConDecl new_or_data res_kind (ConDeclGADT- { con_names = names, con_qvars = explicit_tkv_nms, con_mb_cxt = cxt- , con_g_args = args, con_res_ty = res_ty, con_g_ext = implicit_tkv_nms })+ { con_names = names, con_bndrs = L _ outer_bndrs, con_mb_cxt = cxt+ , con_g_args = args, con_res_ty = res_ty }) = -- Even though the GADT-style data constructor's type is closed, -- we must still kind-check the type, because that may influence -- the inferred kind of the /type/ constructor. Example:@@ -1646,9 +1648,8 @@ -- If we don't look at MkT we won't get the correct kind -- for the type constructor T addErrCtxt (dataConCtxtName names) $- discardResult $- bindImplicitTKBndrs_Tv implicit_tkv_nms $- bindExplicitTKBndrs_Tv explicit_tkv_nms $+ discardResult $+ bindOuterSigTKBndrs_Tv outer_bndrs $ -- Why "_Tv"? See Note [Kind-checking for GADTs] do { _ <- tcHsMbContext cxt ; kcConGADTArgs new_or_data res_kind args@@ -2437,11 +2438,10 @@ tcDefaultAssocDecl fam_tc [L loc (TyFamInstDecl { tfid_eqn =- HsIB { hsib_ext = imp_vars- , hsib_body = FamEqn { feqn_tycon = L _ tc_name- , feqn_bndrs = mb_expl_bndrs+ FamEqn { feqn_tycon = L _ tc_name+ , feqn_bndrs = outer_bndrs , feqn_pats = hs_pats- , feqn_rhs = hs_rhs_ty }}})]+ , feqn_rhs = hs_rhs_ty }})] = -- See Note [Type-checking default assoc decls] setSrcSpan loc $ tcAddFamInstCtxt (text "default type instance") tc_name $@@ -2465,8 +2465,7 @@ -- type default LHS can mention *different* type variables than the -- enclosing class. So it's treated more as a freestanding beast. ; (qtvs, pats, rhs_ty) <- tcTyFamInstEqnGuts fam_tc NotAssociated- imp_vars (mb_expl_bndrs `orElse` [])- hs_pats hs_rhs_ty+ outer_bndrs hs_pats hs_rhs_ty ; let fam_tvs = tyConTyVars fam_tc ; traceTc "tcDefaultAssocDecl 2" (vcat@@ -2845,17 +2844,15 @@ -- Used for the equations of a closed type family only -- Not used for data/type instances kcTyFamInstEqn tc_fam_tc- (L loc (HsIB { hsib_ext = imp_vars- , hsib_body = FamEqn { feqn_tycon = L _ eqn_tc_name- , feqn_bndrs = mb_expl_bndrs- , feqn_pats = hs_pats- , feqn_rhs = hs_rhs_ty }}))+ (L loc (FamEqn { feqn_tycon = L _ eqn_tc_name+ , feqn_bndrs = outer_bndrs+ , feqn_pats = hs_pats+ , feqn_rhs = hs_rhs_ty })) = setSrcSpan loc $ do { traceTc "kcTyFamInstEqn" (vcat [ text "tc_name =" <+> ppr eqn_tc_name , text "fam_tc =" <+> ppr tc_fam_tc <+> dcolon <+> ppr (tyConKind tc_fam_tc)- , text "hsib_vars =" <+> ppr imp_vars- , text "feqn_bndrs =" <+> ppr mb_expl_bndrs+ , text "feqn_bndrs =" <+> ppr outer_bndrs , text "feqn_pats =" <+> ppr hs_pats ]) -- this check reports an arity error instead of a kind error; easier for user ; let vis_pats = numVisibleArgs hs_pats@@ -2871,8 +2868,7 @@ wrongNumberOfParmsErr vis_arity ; discardResult $- bindImplicitTKBndrs_Q_Tv imp_vars $- bindExplicitTKBndrs_Q_Tv AnyKind (mb_expl_bndrs `orElse` []) $+ bindOuterFamEqnTKBndrs_Q_Tv outer_bndrs $ do { (_fam_app, res_kind) <- tcFamTyPats tc_fam_tc hs_pats ; tcCheckLHsType hs_rhs_ty (TheKind res_kind) } -- Why "_Tv" here? Consider (#14066@@ -2892,13 +2888,12 @@ -- (typechecked here) have TyFamInstEqns tcTyFamInstEqn fam_tc mb_clsinfo- (L loc (HsIB { hsib_ext = imp_vars- , hsib_body = FamEqn { feqn_bndrs = mb_expl_bndrs- , feqn_pats = hs_pats- , feqn_rhs = hs_rhs_ty }}))+ (L loc (FamEqn { feqn_bndrs = outer_bndrs+ , feqn_pats = hs_pats+ , feqn_rhs = hs_rhs_ty })) = setSrcSpan loc $ do { traceTc "tcTyFamInstEqn" $- vcat [ ppr fam_tc <+> ppr hs_pats+ vcat [ ppr loc, ppr fam_tc <+> ppr hs_pats , text "fam tc bndrs" <+> pprTyVars (tyConTyVars fam_tc) , case mb_clsinfo of NotAssociated {} -> empty@@ -2914,24 +2909,15 @@ ; checkTc (vis_pats == vis_arity) $ wrongNumberOfParmsErr vis_arity ; (qtvs, pats, rhs_ty) <- tcTyFamInstEqnGuts fam_tc mb_clsinfo- imp_vars (mb_expl_bndrs `orElse` [])- hs_pats hs_rhs_ty+ outer_bndrs hs_pats hs_rhs_ty -- Don't print results they may be knot-tied -- (tcFamInstEqnGuts zonks to Type) ; return (mkCoAxBranch qtvs [] [] pats rhs_ty (map (const Nominal) qtvs) loc) } -{--Kind check type patterns and kind annotate the embedded type variables.- type instance F [a] = rhs-- * Here we check that a type instance matches its kind signature, but we do- not check whether there is a pattern for each type index; the latter- check is only required for type synonym instances.--Note [Instantiating a family tycon]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+{- Note [Instantiating a family tycon]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ It's possible that kind-checking the result of a family tycon applied to its patterns will instantiate the tycon further. For example, we might have@@ -2960,20 +2946,31 @@ such as Proxy * wildcards such as '_' above -So, the simple thing is- - Gather candidates from the LHS- - Include any user-specified forall'd variables, so that we get an- error from Validity.checkFamPatBinders if a forall'd variable is- not bound on the LHS- - Quantify over them+The wildcards are particularly awkward: they may need to be quantified+ - before the explicit variables k,a,b+ - after them+ - or even interleaved with them+ c.f. Note [Naughty quantification candidates] in GHC.Tc.Utils.TcMType -Note that, unlike a type signature like- f :: forall (a::k). blah-we do /not/ care about the Inferred/Specified designation-or order for the final quantified tyvars. Type-family-instances are not invoked directly in Haskell source code,-so visible type application etc plays no role.+So, we use bindOuterFamEqnTKBndrs (which does not create an implication for+the telescope), and generalise over /all/ the variables in the LHS,+without treating the explicitly-quanfitifed ones specially. Wrinkles: + - When generalising, include the explicit user-specified forall'd+ variables, so that we get an error from Validity.checkFamPatBinders+ if a forall'd variable is not bound on the LHS++ - We still want to complain about a bad telescope among the user-specified+ variables. So in checkFamTelescope we emit an implication constraint+ quantifying only over them, purely so that we get a good telescope error.++ - Note that, unlike a type signature like+ f :: forall (a::k). blah+ we do /not/ care about the Inferred/Specified designation or order for+ the final quantified tyvars. Type-family instances are not invoked+ directly in Haskell source code, so visible type application etc plays+ no role.+ See also Note [Re-quantify type variables in rules] in GHC.Tc.Gen.Rule, which explains a /very/ similar design when generalising over the type of a rewrite rule.@@ -2982,12 +2979,12 @@ -------------------------- tcTyFamInstEqnGuts :: TyCon -> AssocInstInfo- -> [Name] -> [LHsTyVarBndr () GhcRn] -- Implicit and explicit binder+ -> HsOuterFamEqnTyVarBndrs GhcRn -- Implicit and explicit binders -> HsTyPats GhcRn -- Patterns -> LHsType GhcRn -- RHS -> TcM ([TyVar], [TcType], TcType) -- (tyvars, pats, rhs) -- Used only for type families, not data families-tcTyFamInstEqnGuts fam_tc mb_clsinfo imp_vars exp_bndrs hs_pats hs_rhs_ty+tcTyFamInstEqnGuts fam_tc mb_clsinfo outer_hs_bndrs hs_pats hs_rhs_ty = do { traceTc "tcTyFamInstEqnGuts {" (ppr fam_tc) -- By now, for type families (but not data families) we should@@ -2995,10 +2992,9 @@ -- This code is closely related to the code -- in GHC.Tc.Gen.HsType.kcCheckDeclHeader_cusk- ; (tclvl, wanted, (imp_tvs, (exp_tvs, (lhs_ty, rhs_ty))))+ ; (tclvl, wanted, (outer_tvs, (lhs_ty, rhs_ty))) <- pushLevelAndSolveEqualitiesX "tcTyFamInstEqnGuts" $- bindImplicitTKBndrs_Q_Skol imp_vars $- bindExplicitTKBndrs_Q_Skol AnyKind exp_bndrs $+ bindOuterFamEqnTKBndrs outer_hs_bndrs $ do { (lhs_ty, rhs_kind) <- tcFamTyPats fam_tc hs_pats -- Ensure that the instance is consistent with its -- parent class (#16008)@@ -3013,9 +3009,10 @@ -- check there too! -- See Note [Generalising in tcTyFamInstEqnGuts]- ; dvs <- candidateQTyVarsOfTypes (lhs_ty : mkTyVarTys (imp_tvs ++ exp_tvs))+ ; dvs <- candidateQTyVarsOfTypes (lhs_ty : mkTyVarTys outer_tvs) ; qtvs <- quantifyTyVars dvs ; reportUnsolvedEqualities FamInstSkol qtvs tclvl wanted+ ; checkFamTelescope tclvl outer_hs_bndrs outer_tvs ; traceTc "tcTyFamInstEqnGuts 2" $ vcat [ ppr fam_tc@@ -3033,6 +3030,22 @@ ; traceTc "tcTyFamInstEqnGuts }" (ppr fam_tc <+> pprTyVars qtvs) ; return (qtvs, pats, rhs_ty) } ++checkFamTelescope :: TcLevel -> HsOuterFamEqnTyVarBndrs GhcRn+ -> [TcTyVar] -> TcM ()+-- Emit a constraint (forall a b c. <empty>), so that+-- we will do telescope-checking on a,b,c+-- See Note [Generalising in tcTyFamInstEqnGuts]+checkFamTelescope tclvl hs_outer_bndrs outer_tvs+ | HsOuterExplicit { hso_bndrs = bndrs } <- hs_outer_bndrs+ , (b_first : _) <- bndrs+ , let b_last = last bndrs+ skol_info = ForAllSkol (fsep (map ppr bndrs))+ = setSrcSpan (combineSrcSpans (getLoc b_first) (getLoc b_last)) $+ emitResidualTvConstraint skol_info outer_tvs tclvl emptyWC+ | otherwise+ = return ()+ ----------------- unravelFamInstPats :: TcType -> [TcType] -- Decompose fam_app to get the argument patterns@@ -3218,8 +3231,8 @@ ; traceTc "tcConDecl 1" (vcat [ ppr name, ppr explicit_tkv_nms ]) ; (tclvl, wanted, (exp_tvbndrs, (ctxt, arg_tys, field_lbls, stricts)))- <- pushLevelAndSolveEqualitiesX "tcConDecl:H98" $- bindExplicitTKBndrs_Skol explicit_tkv_nms $+ <- pushLevelAndSolveEqualitiesX "tcConDecl:H98" $+ tcExplicitTKBndrs explicit_tkv_nms $ do { ctxt <- tcHsMbContext hs_ctxt ; let exp_kind = getArgExpKind new_or_data res_kind ; btys <- tcConH98Args exp_kind hs_args@@ -3248,7 +3261,7 @@ ; kvs <- kindGeneralizeAll fake_ty - ; let skol_tvs = kvs ++ tmpl_tvs ++ binderVars exp_tvbndrs+ ; let skol_tvs = kvs ++ tmpl_tvs ; reportUnsolvedEqualities skol_info skol_tvs tclvl wanted -- Zonk to Types@@ -3289,19 +3302,17 @@ tcConDecl rep_tycon tag_map tmpl_bndrs _res_kind res_tmpl new_or_data -- NB: don't use res_kind here, as it's ill-scoped. Instead, -- we get the res_kind by typechecking the result type.- (ConDeclGADT { con_g_ext = implicit_tkv_nms- , con_names = names- , con_qvars = explicit_tkv_nms+ (ConDeclGADT { con_names = names+ , con_bndrs = L _ outer_hs_bndrs , con_mb_cxt = cxt, con_g_args = hs_args , con_res_ty = hs_res_ty }) = addErrCtxt (dataConCtxtName names) $ do { traceTc "tcConDecl 1 gadt" (ppr names) ; let (L _ name : _) = names - ; (tclvl, wanted, (imp_tvs, (exp_tvbndrs, (ctxt, arg_tys, res_ty, field_lbls, stricts))))+ ; (tclvl, wanted, (outer_bndrs, (ctxt, arg_tys, res_ty, field_lbls, stricts))) <- pushLevelAndSolveEqualitiesX "tcConDecl:GADT" $- bindImplicitTKBndrs_Skol implicit_tkv_nms $- bindExplicitTKBndrs_Skol explicit_tkv_nms $+ tcOuterTKBndrs skol_info outer_hs_bndrs $ do { ctxt <- tcHsMbContext cxt ; (res_ty, res_kind) <- tcInferLHsTypeKind hs_res_ty -- See Note [GADT return kinds]@@ -3314,20 +3325,18 @@ ; field_lbls <- lookupConstructorFields name ; return (ctxt, arg_tys, res_ty, field_lbls, stricts) }- ; imp_tvs <- zonkAndScopedSort imp_tvs- ; let con_ty = mkSpecForAllTys imp_tvs $- mkInvisForAllTys exp_tvbndrs $- mkPhiTy ctxt $- mkVisFunTys arg_tys $- res_ty- ; kvs <- kindGeneralizeAll con_ty - ; let tvbndrs = mkTyVarBinders InferredSpec kvs- ++ mkTyVarBinders SpecifiedSpec imp_tvs- ++ exp_tvbndrs+ ; outer_tv_bndrs <- scopedSortOuter outer_bndrs - ; reportUnsolvedEqualities skol_info (binderVars tvbndrs) tclvl wanted+ ; tkvs <- kindGeneralizeAll (mkInvisForAllTys outer_tv_bndrs $+ mkPhiTy ctxt $+ mkVisFunTys arg_tys $+ res_ty)+ ; traceTc "tcConDecl:GADT" (ppr names $$ ppr res_ty $$ ppr tkvs)+ ; reportUnsolvedEqualities skol_info tkvs tclvl wanted + ; let tvbndrs = mkTyVarBinders InferredSpec tkvs ++ outer_tv_bndrs+ -- Zonk to Types ; (ze, tvbndrs) <- zonkTyVarBinders tvbndrs ; arg_tys <- zonkScaledTcTypesToTypesX ze arg_tys@@ -4825,8 +4834,7 @@ = tcAddFamInstCtxt (text "type instance") (tyFamInstDeclName decl) tcMkDataFamInstCtxt :: DataFamInstDecl GhcRn -> SDoc-tcMkDataFamInstCtxt decl@(DataFamInstDecl { dfid_eqn =- HsIB { hsib_body = eqn }})+tcMkDataFamInstCtxt decl@(DataFamInstDecl { dfid_eqn = eqn }) = tcMkFamInstCtxt (pprDataFamInstFlavour decl <+> text "instance") (unLoc (feqn_tycon eqn))
compiler/GHC/Tc/TyCl/Class.hs view
@@ -157,16 +157,14 @@ dm_bind_names :: [Name] -- These ones have a value binding in the class decl dm_bind_names = [op | L _ (FunBind {fun_id = L _ op}) <- bagToList def_methods] - skol_info = TyConSkol ClassFlavour clas- tc_sig :: NameEnv (SrcSpan, Type) -> ([Located Name], LHsSigType GhcRn) -> TcM [TcMethInfo] tc_sig gen_dm_env (op_names, op_hs_ty) = do { traceTc "ClsSig 1" (ppr op_names)- ; op_ty <- tcClassSigType skol_info op_names op_hs_ty+ ; op_ty <- tcClassSigType op_names op_hs_ty -- Class tyvars already in scope - ; traceTc "ClsSig 2" (ppr op_names)+ ; traceTc "ClsSig 2" (ppr op_names $$ ppr op_ty) ; return [ (op_name, op_ty, f op_name) | L _ op_name <- op_names ] } where f nm | Just lty <- lookupNameEnv gen_dm_env nm = Just (GenericDM lty)@@ -174,7 +172,7 @@ | otherwise = Nothing tc_gen_sig (op_names, gen_hs_ty)- = do { gen_op_ty <- tcClassSigType skol_info op_names gen_hs_ty+ = do { gen_op_ty <- tcClassSigType op_names gen_hs_ty ; return [ (op_name, (loc, gen_op_ty)) | L loc op_name <- op_names ] } {-@@ -290,7 +288,7 @@ ; let local_dm_id = mkLocalId local_dm_name Many local_dm_ty local_dm_sig = CompleteSig { sig_bndr = local_dm_id , sig_ctxt = ctxt- , sig_loc = getLoc (hsSigType hs_ty) }+ , sig_loc = getLoc hs_ty } ; (ev_binds, (tc_bind, _)) <- checkConstraints skol_info tyvars [this_dict] $
compiler/GHC/Tc/TyCl/Instance.hs view
@@ -496,7 +496,7 @@ -- See Note [Associated data family instances and di_scoped_tvs]. tv_skol_env = mkVarEnv $ map swap tv_skol_prs n_inferred = countWhile ((== Inferred) . binderArgFlag) $- fst $ splitForAllVarBndrs dfun_ty+ fst $ splitForAllTyCoVarBinders dfun_ty visible_skol_tvs = drop n_inferred skol_tvs ; traceTc "tcLocalInstDecl 1" (ppr dfun_ty $$ ppr (invisibleTyBndrCount dfun_ty) $$ ppr skol_tvs)@@ -531,7 +531,7 @@ -- Finally, construct the Core representation of the instance. -- (This no longer includes the associated types.)- ; dfun_name <- newDFunName clas inst_tys (getLoc (hsSigType hs_ty))+ ; dfun_name <- newDFunName clas inst_tys (getLoc hs_ty) -- Dfun location is that of instance *header* ; ispec <- newClsInst (fmap unLoc overlap_mode) dfun_name@@ -559,7 +559,6 @@ defined_ats = mkNameSet (map (tyFamInstDeclName . unLoc) ats) `unionNameSet` mkNameSet (map (unLoc . feqn_tycon- . hsib_body . dfid_eqn . unLoc) adts) @@ -583,7 +582,7 @@ tcTyFamInstDecl mb_clsinfo (L loc decl@(TyFamInstDecl { tfid_eqn = eqn })) = setSrcSpan loc $ tcAddTyFamInstCtxt decl $- do { let fam_lname = feqn_tycon (hsib_body eqn)+ do { let fam_lname = feqn_tycon eqn ; fam_tc <- tcLookupLocatedTyCon fam_lname ; tcFamInstDeclChecks mb_clsinfo fam_tc @@ -592,10 +591,11 @@ ; checkTc (isOpenTypeFamilyTyCon fam_tc) (notOpenFamily fam_tc) -- (1) do the work of verifying the synonym group+ -- For some reason we don't have a location for the equation+ -- itself, so we make do with the location of family name ; co_ax_branch <- tcTyFamInstEqn fam_tc mb_clsinfo (L (getLoc fam_lname) eqn) - -- (2) check for validity ; checkConsistentFamInst mb_clsinfo fam_tc co_ax_branch ; checkValidCoAxBranch fam_tc co_ax_branch@@ -665,9 +665,8 @@ -> LDataFamInstDecl GhcRn -> TcM (FamInst, Maybe DerivInfo) -- "newtype instance" and "data instance" tcDataFamInstDecl mb_clsinfo tv_skol_env- (L loc decl@(DataFamInstDecl { dfid_eqn = HsIB { hsib_ext = imp_vars- , hsib_body =- FamEqn { feqn_bndrs = mb_bndrs+ (L loc decl@(DataFamInstDecl { dfid_eqn =+ FamEqn { feqn_bndrs = outer_bndrs , feqn_pats = hs_pats , feqn_tycon = lfam_name@(L _ fam_name) , feqn_fixity = fixity@@ -676,7 +675,7 @@ , dd_ctxt = hs_ctxt , dd_cons = hs_cons , dd_kindSig = m_ksig- , dd_derivs = derivs } }}}))+ , dd_derivs = derivs } }})) = setSrcSpan loc $ tcAddDataFamInstCtxt decl $ do { fam_tc <- tcLookupLocatedTyCon lfam_name@@ -689,7 +688,7 @@ -- Do /not/ check that the number of patterns = tyConArity fam_tc -- See [Arity of data families] in GHC.Core.FamInstEnv ; (qtvs, pats, res_kind, stupid_theta)- <- tcDataFamInstHeader mb_clsinfo fam_tc imp_vars mb_bndrs+ <- tcDataFamInstHeader mb_clsinfo fam_tc outer_bndrs fixity hs_ctxt hs_pats m_ksig hs_cons new_or_data @@ -856,7 +855,7 @@ ----------------------- tcDataFamInstHeader- :: AssocInstInfo -> TyCon -> [Name] -> Maybe [LHsTyVarBndr () GhcRn]+ :: AssocInstInfo -> TyCon -> HsOuterFamEqnTyVarBndrs GhcRn -> LexicalFixity -> LHsContext GhcRn -> HsTyPats GhcRn -> Maybe (LHsKind GhcRn) -> [LConDecl GhcRn] -> NewOrData@@ -865,13 +864,12 @@ -- the data constructors themselves -- e.g. data instance D [a] :: * -> * where ... -- Here the "header" is the bit before the "where"-tcDataFamInstHeader mb_clsinfo fam_tc imp_vars mb_bndrs fixity+tcDataFamInstHeader mb_clsinfo fam_tc outer_bndrs fixity hs_ctxt hs_pats m_ksig hs_cons new_or_data = do { traceTc "tcDataFamInstHeader {" (ppr fam_tc <+> ppr hs_pats)- ; (tclvl, wanted, (imp_tvs, (exp_tvs, (stupid_theta, lhs_ty, master_res_kind, instance_res_kind))))+ ; (tclvl, wanted, (scoped_tvs, (stupid_theta, lhs_ty, master_res_kind, instance_res_kind))) <- pushLevelAndSolveEqualitiesX "tcDataFamInstHeader" $- bindImplicitTKBndrs_Q_Skol imp_vars $- bindExplicitTKBndrs_Q_Skol AnyKind exp_bndrs $+ bindOuterFamEqnTKBndrs outer_bndrs $ do { stupid_theta <- tcHsContext hs_ctxt ; (lhs_ty, lhs_kind) <- tcFamTyPats fam_tc hs_pats ; (lhs_applied_ty, lhs_applied_kind)@@ -909,7 +907,7 @@ -- check there too! -- See GHC.Tc.TyCl Note [Generalising in tcFamTyPatsGuts]- ; dvs <- candidateQTyVarsOfTypes (lhs_ty : mkTyVarTys (imp_tvs ++ exp_tvs))+ ; dvs <- candidateQTyVarsOfTypes (lhs_ty : mkTyVarTys scoped_tvs) ; qtvs <- quantifyTyVars dvs ; reportUnsolvedEqualities FamInstSkol qtvs tclvl wanted @@ -937,9 +935,8 @@ ; return (qtvs, pats, master_res_kind, stupid_theta) } where- fam_name = tyConName fam_tc- data_ctxt = DataKindCtxt fam_name- exp_bndrs = mb_bndrs `orElse` []+ fam_name = tyConName fam_tc+ data_ctxt = DataKindCtxt fam_name -- See Note [Implementation of UnliftedNewtypes] in GHC.Tc.TyCl, wrinkle (2). tc_kind_sig Nothing@@ -952,8 +949,8 @@ -- See Note [Result kind signature for a data family instance] tc_kind_sig (Just hs_kind) = do { sig_kind <- tcLHsKindSig data_ctxt hs_kind- ; let (tvs, inner_kind) = tcSplitForAllTys sig_kind ; lvl <- getTcLevel+ ; let (tvs, inner_kind) = tcSplitForAllInvisTyVars sig_kind ; (subst, _tvs') <- tcInstSkolTyVarsAt lvl False emptyTCvSubst tvs -- Perhaps surprisingly, we don't need the skolemised tvs themselves ; return (substTy subst inner_kind) }@@ -1802,7 +1799,7 @@ -- There is a signature in the instance -- See Note [Instance method signatures] = do { (sig_ty, hs_wrap)- <- setSrcSpan (getLoc (hsSigType hs_sig_ty)) $+ <- setSrcSpan (getLoc hs_sig_ty) $ do { inst_sigs <- xoptM LangExt.InstanceSigs ; checkTc inst_sigs (misplacedInstSig sel_name hs_sig_ty) ; sig_ty <- tcHsSigType (FunSigCtxt sel_name False) hs_sig_ty@@ -1823,7 +1820,7 @@ inner_meth_id = mkLocalId inner_meth_name Many sig_ty inner_meth_sig = CompleteSig { sig_bndr = inner_meth_id , sig_ctxt = ctxt- , sig_loc = getLoc (hsSigType hs_sig_ty) }+ , sig_loc = getLoc hs_sig_ty } ; (tc_bind, [inner_id]) <- tcPolyCheck no_prag_fn inner_meth_sig meth_bind
compiler/GHC/Tc/TyCl/PatSyn.hs view
@@ -24,6 +24,7 @@ import GHC.Tc.Gen.Pat import GHC.Core.Multiplicity import GHC.Core.Type ( tidyTyCoVarBinders, tidyTypes, tidyType )+import GHC.Core.TyCo.Subst( extendTvSubstWithClone ) import GHC.Tc.Utils.Monad import GHC.Tc.Gen.Sig( emptyPragEnv, completeSigFromId ) import GHC.Tc.Utils.Env@@ -61,7 +62,7 @@ import GHC.Utils.Error import Data.Maybe( mapMaybe ) import Control.Monad ( zipWithM )-import Data.List( partition )+import Data.List( partition, mapAccumL ) #include "GhclibHsVersions.h" @@ -345,24 +346,24 @@ tcCheckPatSynDecl psb@PSB{ psb_id = lname@(L _ name), psb_args = details , psb_def = lpat, psb_dir = dir } TPSI{ patsig_implicit_bndrs = implicit_bndrs- , patsig_univ_bndrs = explicit_univ_bndrs, patsig_prov = prov_theta- , patsig_ex_bndrs = explicit_ex_bndrs, patsig_req = req_theta+ , patsig_univ_bndrs = explicit_univ_bndrs, patsig_req = req_theta+ , patsig_ex_bndrs = explicit_ex_bndrs, patsig_prov = prov_theta , patsig_body_ty = sig_body_ty } = addPatSynCtxt lname $- do { let decl_arity = length arg_names- (arg_names, rec_fields, is_infix) = collectPatSynArgInfo details-- ; traceTc "tcCheckPatSynDecl" $+ do { traceTc "tcCheckPatSynDecl" $ vcat [ ppr implicit_bndrs, ppr explicit_univ_bndrs, ppr req_theta , ppr explicit_ex_bndrs, ppr prov_theta, ppr sig_body_ty ] + ; let decl_arity = length arg_names+ (arg_names, rec_fields, is_infix) = collectPatSynArgInfo details+ ; (arg_tys, pat_ty) <- case tcSplitFunTysN decl_arity sig_body_ty of Right stuff -> return stuff Left missing -> wrongNumberOfParmsErr name decl_arity missing -- Complain about: pattern P :: () => forall x. x -> P x -- The existential 'x' should not appear in the result type- -- Can't check this until we know P's arity+ -- Can't check this until we know P's arity (decl_arity above) ; let bad_tvs = filter (`elemVarSet` tyCoVarsOfType pat_ty) $ binderVars explicit_ex_bndrs ; checkTc (null bad_tvs) $ hang (sep [ text "The result type of the signature for" <+> quotes (ppr name) <> comma@@ -379,36 +380,55 @@ univ_tvs = binderVars univ_bndrs ex_tvs = binderVars ex_bndrs + -- Skolemise the quantified type variables. This is necessary+ -- in order to check the actual pattern type against the+ -- expected type. Even though the tyvars in the type are+ -- already skolems, this step changes their TcLevels,+ -- avoiding level-check errors when unifying.+ ; (skol_subst0, skol_univ_bndrs) <- skolemiseTvBndrsX emptyTCvSubst univ_bndrs+ ; (skol_subst, skol_ex_bndrs) <- skolemiseTvBndrsX skol_subst0 ex_bndrs+ ; let skol_univ_tvs = binderVars skol_univ_bndrs+ skol_ex_tvs = binderVars skol_ex_bndrs+ skol_req_theta = substTheta skol_subst0 req_theta+ skol_prov_theta = substTheta skol_subst prov_theta+ skol_arg_tys = substTys skol_subst (map scaledThing arg_tys)+ skol_pat_ty = substTy skol_subst pat_ty++ univ_tv_prs = [ (getName orig_univ_tv, skol_univ_tv)+ | (orig_univ_tv, skol_univ_tv) <- univ_tvs `zip` skol_univ_tvs ]+ -- Right! Let's check the pattern against the signature -- See Note [Checking against a pattern signature]- ; req_dicts <- newEvVars req_theta+ ; req_dicts <- newEvVars skol_req_theta ; (tclvl, wanted, (lpat', (ex_tvs', prov_dicts, args'))) <- ASSERT2( equalLength arg_names arg_tys, ppr name $$ ppr arg_names $$ ppr arg_tys ) pushLevelAndCaptureConstraints $- tcExtendTyVarEnv univ_tvs $- tcCheckPat PatSyn lpat (unrestricted pat_ty) $- do { let in_scope = mkInScopeSet (mkVarSet univ_tvs)+ tcExtendNameTyVarEnv univ_tv_prs $+ tcCheckPat PatSyn lpat (unrestricted skol_pat_ty) $+ do { let in_scope = mkInScopeSet (mkVarSet skol_univ_tvs) empty_subst = mkEmptyTCvSubst in_scope- ; (subst, ex_tvs') <- mapAccumLM newMetaTyVarX empty_subst ex_tvs+ ; (inst_subst, ex_tvs') <- mapAccumLM newMetaTyVarX empty_subst skol_ex_tvs -- newMetaTyVarX: see the "Existential type variables" -- part of Note [Checking against a pattern signature] ; traceTc "tcpatsyn1" (vcat [ ppr v <+> dcolon <+> ppr (tyVarKind v) | v <- ex_tvs]) ; traceTc "tcpatsyn2" (vcat [ ppr v <+> dcolon <+> ppr (tyVarKind v) | v <- ex_tvs'])- ; let prov_theta' = substTheta subst prov_theta+ ; let prov_theta' = substTheta inst_subst skol_prov_theta -- Add univ_tvs to the in_scope set to -- satisfy the substitution invariant. There's no need to -- add 'ex_tvs' as they are already in the domain of the -- substitution. -- See also Note [The substitution invariant] in GHC.Core.TyCo.Subst. ; prov_dicts <- mapM (emitWanted (ProvCtxtOrigin psb)) prov_theta'- ; args' <- zipWithM (tc_arg subst) arg_names (map scaledThing arg_tys)+ ; args' <- zipWithM (tc_arg inst_subst) arg_names+ skol_arg_tys ; return (ex_tvs', prov_dicts, args') } ; let skol_info = SigSkol (PatSynCtxt name) pat_ty [] -- The type here is a bit bogus, but we do not print -- the type for PatSynCtxt, so it doesn't matter -- See Note [Skolem info for pattern synonyms] in "GHC.Tc.Types.Origin"- ; (implics, ev_binds) <- buildImplicationFor tclvl skol_info univ_tvs req_dicts wanted+ ; (implics, ev_binds) <- buildImplicationFor tclvl skol_info skol_univ_tvs+ req_dicts wanted -- Solve the constraints now, because we are about to make a PatSyn, -- which should not contain unification variables and the like (#10997)@@ -419,11 +439,12 @@ -- when that should be impossible ; traceTc "tcCheckPatSynDecl }" $ ppr name+ ; tc_patsyn_finish lname dir is_infix lpat'- (univ_bndrs, req_theta, ev_binds, req_dicts)- (ex_bndrs, mkTyVarTys ex_tvs', prov_theta, prov_dicts)- (args', map scaledThing arg_tys)- pat_ty rec_fields }+ (skol_univ_bndrs, skol_req_theta, ev_binds, req_dicts)+ (skol_ex_bndrs, mkTyVarTys ex_tvs', skol_prov_theta, prov_dicts)+ (args', skol_arg_tys)+ skol_pat_ty rec_fields } where tc_arg :: TCvSubst -> Name -> Type -> TcM (LHsExpr GhcTc) -- Look up the variable actually bound by lpat@@ -440,13 +461,50 @@ do { arg_id <- tcLookupId arg_name ; wrap <- tcSubTypeSigma GenSigCtxt (idType arg_id)- (substTyUnchecked subst arg_ty)+ (substTy subst arg_ty) -- Why do we need tcSubType here? -- See Note [Pattern synonyms and higher rank types] ; return (mkLHsWrap wrap $ nlHsVar arg_id) } -{- [Pattern synonyms and higher rank types]-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+skolemiseTvBndrsX :: TCvSubst -> [VarBndr TyVar flag]+ -> TcM (TCvSubst, [VarBndr TcTyVar flag])+-- Make new TcTyVars, all skolems with levels, but do not clone+-- The level is one level deeper than the current level+-- See Note [Skolemising when checking a pattern synonym]+skolemiseTvBndrsX orig_subst tvs+ = do { tc_lvl <- getTcLevel+ ; let pushed_lvl = pushTcLevel tc_lvl+ details = SkolemTv pushed_lvl False++ mk_skol_tv_x :: TCvSubst -> VarBndr TyVar flag+ -> (TCvSubst, VarBndr TcTyVar flag)+ mk_skol_tv_x subst (Bndr tv flag)+ = (subst', Bndr new_tv flag)+ where+ new_kind = substTyUnchecked subst (tyVarKind tv)+ new_tv = mkTcTyVar (tyVarName tv) new_kind details+ subst' = extendTvSubstWithClone subst tv new_tv++ ; return (mapAccumL mk_skol_tv_x orig_subst tvs) }++{- Note [Skolemising when checking a pattern synonym]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+Consider+ pattern P1 :: forall a. a -> Maybe a+ pattern P1 x <- Just x where+ P1 x = Just (x :: a)++The scoped type variable 'a' scopes over the builder RHS, Just (x::a).+But the builder RHS is typechecked much later in tcPatSynBuilderBind,+and gets its scoped type variables from the type of the builder_id.+The easiest way to achieve this is not to clone when skolemising.++Hence a special-purpose skolemiseTvBndrX here, similar to+GHC.Tc.Utils.Instantiate.tcInstSkolTyVarsX except that the latter+does cloning.++[Pattern synonyms and higher rank types]+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consider data T = MkT (forall a. a->a)
compiler/GHC/Tc/Utils/Backpack.hs view
@@ -223,8 +223,8 @@ skol_info = InstSkol -- Based off of tcSplitDFunTy (tvs, theta, pred) =- case tcSplitForAllTys ty of { (tvs, rho) ->- case splitFunTys rho of { (theta, pred) ->+ case tcSplitForAllInvisTyVars ty of { (tvs, rho) ->+ case splitFunTys rho of { (theta, pred) -> (tvs, theta, pred) }} origin = InstProvidedOrigin (tcg_semantic_mod tcg_env) sig_inst (skol_subst, tvs_skols) <- tcInstSkolTyVars tvs -- Skolemize
compiler/GHC/Tc/Utils/Env.hs view
@@ -734,8 +734,8 @@ = concatMap (get_fi_cons . unLoc) fids get_fi_cons :: DataFamInstDecl GhcRn -> [Name]- get_fi_cons (DataFamInstDecl { dfid_eqn = HsIB { hsib_body =- FamEqn { feqn_rhs = HsDataDefn { dd_cons = cons } }}})+ get_fi_cons (DataFamInstDecl { dfid_eqn =+ FamEqn { feqn_rhs = HsDataDefn { dd_cons = cons } }}) = map unLoc $ concatMap (getConNames . unLoc) cons
compiler/GHC/Tc/Utils/Instantiate.hs view
@@ -464,7 +464,7 @@ subst' = extendTCvInScopeSet subst (tyCoVarsOfType rho) ; return (tv_prs, substTheta subst' theta, substTy subst' tau) } where- (tyvars, rho) = tcSplitForAllTys (idType id)+ (tyvars, rho) = tcSplitForAllInvisTyVars (idType id) (theta, tau) = tcSplitPhiTy rho tcInstTypeBndrs :: Id -> TcM ([(Name, InvisTVBinder)], TcThetaType, TcType)@@ -480,7 +480,7 @@ subst' = extendTCvInScopeSet subst (tyCoVarsOfType rho) ; return (tv_prs, substTheta subst' theta, substTy subst' tau) } where- (tyvars, rho) = splitForAllTysInvis (idType id)+ (tyvars, rho) = splitForAllInvisTVBinders (idType id) (theta, tau) = tcSplitPhiTy rho inst_invis_bndr :: TCvSubst -> InvisTVBinder@@ -491,7 +491,7 @@ tcSkolDFunType :: DFunId -> TcM ([TcTyVar], TcThetaType, TcType) -- Instantiate a type signature with skolem constants.--- We could give them fresh names, but no need to do so+-- This freshens the names, but no need to do so tcSkolDFunType dfun = do { (tv_prs, theta, tau) <- tcInstType tcInstSuperSkolTyVars dfun ; return (map snd tv_prs, theta, tau) }@@ -523,13 +523,18 @@ tcInstSuperSkolTyVars :: [TyVar] -> TcM (TCvSubst, [TcTyVar]) -- See Note [Skolemising type variables]+-- This version freshens the names and creates "super skolems";+-- see comments around superSkolemTv. tcInstSuperSkolTyVars = tcInstSuperSkolTyVarsX emptyTCvSubst tcInstSuperSkolTyVarsX :: TCvSubst -> [TyVar] -> TcM (TCvSubst, [TcTyVar]) -- See Note [Skolemising type variables]+-- This version freshens the names and creates "super skolems";+-- see comments around superSkolemTv. tcInstSuperSkolTyVarsX subst = tcInstSkolTyVarsPushLevel True subst -tcInstSkolTyVarsPushLevel :: Bool -> TCvSubst -> [TyVar]+tcInstSkolTyVarsPushLevel :: Bool -- True <=> make "super skolem"+ -> TCvSubst -> [TyVar] -> TcM (TCvSubst, [TcTyVar]) -- Skolemise one level deeper, hence pushTcLevel -- See Note [Skolemising type variables]@@ -598,10 +603,22 @@ b) The [TyVar] should be ordered (kind vars first) See Note [Kind substitution when instantiating] -c) It's a complete freshening operation: the skolems have a fresh- unique, and a location from the monad+c) Clone the variable to give a fresh unique. This is essential.+ Consider (tc160)+ type Foo x = forall a. a -> x+ And typecheck the expression+ (e :: Foo (Foo ())+ We will skolemise the signature, but after expanding synonyms it+ looks like+ forall a. a -> forall a. a -> x+ We don't want to make two big-lambdas with the same unique! -d) The resulting skolems are+d) We retain locations. Because the location of the variable is the correct+ location to report in errors (e.g. in the signature). We don't want the+ location to change to the body of the function, which does *not* explicitly+ bind the variable.++e) The resulting skolems are non-overlappable for tcInstSkolTyVars, but overlappable for tcInstSuperSkolTyVars See GHC.Tc.Deriv.Infer Note [Overlap and deriving] for an example
compiler/GHC/Tc/Utils/Monad.hs view
@@ -28,7 +28,7 @@ whenDOptM, whenGOptM, whenWOptM, whenXOptM, unlessXOptM, getGhcMode,- withDoDynamicToo,+ withDynamicNow, withoutDynamicNow, getEpsVar, getEps, updateEps, updateEps_,@@ -546,11 +546,16 @@ getGhcMode :: TcRnIf gbl lcl GhcMode getGhcMode = do { env <- getTopEnv; return (ghcMode (hsc_dflags env)) } -withDoDynamicToo :: TcRnIf gbl lcl a -> TcRnIf gbl lcl a-withDoDynamicToo =+withDynamicNow :: TcRnIf gbl lcl a -> TcRnIf gbl lcl a+withDynamicNow = updTopEnv (\top@(HscEnv { hsc_dflags = dflags }) ->- top { hsc_dflags = dynamicTooMkDynamicDynFlags dflags })+ top { hsc_dflags = setDynamicNow dflags }) +withoutDynamicNow :: TcRnIf gbl lcl a -> TcRnIf gbl lcl a+withoutDynamicNow =+ updTopEnv (\top@(HscEnv { hsc_dflags = dflags }) ->+ top { hsc_dflags = dflags { dynamicNow = False} })+ getEpsVar :: TcRnIf gbl lcl (TcRef ExternalPackageState) getEpsVar = do { env <- getTopEnv; return (hsc_EPS env) } @@ -1845,8 +1850,8 @@ the visible type application fails in the monad (throws an exception). We must not discard the out-of-scope error. - Also GHC.Tc.Solver.emitFlatConstraints may fail having emitted some- constraints with skolem-escape problems.+ Also GHC.Tc.Solver.simplifyAndEmitFlatConstraints may fail having+ emitted some constraints with skolem-escape problems. * If we discard too /few/ constraints, we may get the misleading class constraints mentioned above. But we may /also/ end up taking
compiler/GHC/Tc/Utils/Unify.hs view
@@ -927,12 +927,17 @@ emitResidualTvConstraint :: SkolemInfo -> [TcTyVar] -> TcLevel -> WantedConstraints -> TcM () emitResidualTvConstraint skol_info skol_tvs tclvl wanted- | isEmptyWC wanted- = return ()-- | otherwise- = do { implic <- buildTvImplication skol_info skol_tvs tclvl wanted+ | not (isEmptyWC wanted) ||+ checkTelescopeSkol skol_info+ = -- checkTelescopeSkol: in this case, /always/ emit this implication+ -- even if 'wanted' is empty. We need the implication so that we check+ -- for a bad telescope. See Note [Skolem escape and forall-types] in+ -- GHC.Tc.Gen.HsType+ do { implic <- buildTvImplication skol_info skol_tvs tclvl wanted ; emitImplication implic }++ | otherwise -- Empty 'wanted', emit nothing+ = return () buildTvImplication :: SkolemInfo -> [TcTyVar] -> TcLevel -> WantedConstraints -> TcM Implication
compiler/GHC/Tc/Validity.hs view
@@ -254,11 +254,11 @@ checkUserTypeError = check where check ty- | Just msg <- userTypeError_maybe ty = fail_with msg- | Just (_,ts) <- splitTyConApp_maybe ty = mapM_ check ts- | Just (t1,t2) <- splitAppTy_maybe ty = check t1 >> check t2- | Just (_,t1) <- splitForAllTy_maybe ty = check t1- | otherwise = return ()+ | Just msg <- userTypeError_maybe ty = fail_with msg+ | Just (_,ts) <- splitTyConApp_maybe ty = mapM_ check ts+ | Just (t1,t2) <- splitAppTy_maybe ty = check t1 >> check t2+ | Just (_,t1) <- splitForAllTyCoVar_maybe ty = check t1+ | otherwise = return () fail_with msg = do { env0 <- tcInitTidyEnv ; let (env1, tidy_msg) = tidyOpenType env0 msg@@ -751,7 +751,7 @@ ; checkEscapingKind env' tvbs' theta tau } where- (tvbs, phi) = tcSplitForAllVarBndrs ty+ (tvbs, phi) = tcSplitForAllTyVarBinders ty (theta, tau) = tcSplitPhiTy phi (env', tvbs') = tidyTyCoVarBinders env tvbs @@ -924,7 +924,7 @@ , vcat [ hang herald 2 (ppr_tidy env ty) , suggestion ] ) where- (tvs, _theta, _tau) = tcSplitSigmaTy ty+ (tvs, _rho) = tcSplitForAllTyVars ty herald | null tvs = text "Illegal qualified type:" | otherwise = text "Illegal polymorphic type:" suggestion = case rank of@@ -1056,7 +1056,7 @@ If the rank-n case came first, then in the process of checking for `forall`s or contexts, we would expand away `B A` to `forall x. x -> x`. This is because the functions that split apart `forall`s/contexts-(tcSplitForAllVarBndrs/tcSplitPhiTy) expand type synonyms! If `B A` is expanded+(tcSplitForAllTyVarBinders/tcSplitPhiTy) expand type synonyms! If `B A` is expanded away to `forall x. x -> x` before the actually validity checks occur, we will have completely obfuscated the fact that we had an unsaturated application of the `A` type synonym.@@ -2855,7 +2855,7 @@ occurred. (It /used/ to be possible; see tests T13983 and T7873. But with the advent of the forall-or-nothing rule for kind variables, those strange cases went away. See Note [forall-or-nothing rule] in-GHC.Rename.HsType.)+GHC.Hs.Type.) But one might worry about type v k = *
compiler/GHC/ThToHs.hs view
@@ -191,14 +191,14 @@ cvtDec (TH.SigD nm typ) = do { nm' <- vNameL nm- ; ty' <- cvtType typ+ ; ty' <- cvtSigType typ ; returnJustL $ Hs.SigD noExtField- (TypeSig noExtField [nm'] (mkLHsSigWcType ty')) }+ (TypeSig noExtField [nm'] (mkHsWildCardBndrs ty')) } cvtDec (TH.KiSigD nm ki) = do { nm' <- tconNameL nm- ; ki' <- cvtType ki- ; let sig' = StandaloneKindSig noExtField nm' (mkLHsSigType ki')+ ; ki' <- cvtSigKind ki+ ; let sig' = StandaloneKindSig noExtField nm' ki' ; returnJustL $ Hs.KindSigD noExtField sig' } cvtDec (TH.InfixD fx nm)@@ -289,9 +289,10 @@ ; unless (null fams') (failWith (mkBadDecMsg doc fams')) ; ctxt' <- cvtContext funPrec ctxt ; (L loc ty') <- cvtType ty- ; let inst_ty' = mkHsQualTy ctxt loc ctxt' $ L loc ty'+ ; let inst_ty' = L loc $ mkHsImplicitSigType $+ mkHsQualTy ctxt loc ctxt' $ L loc ty' ; returnJustL $ InstD noExtField $ ClsInstD noExtField $- ClsInstDecl { cid_ext = noExtField, cid_poly_ty = mkLHsSigType inst_ty'+ ClsInstDecl { cid_ext = noExtField, cid_poly_ty = inst_ty' , cid_binds = binds' , cid_sigs = Hs.mkClassOpSigs sigs' , cid_tyfam_insts = ats', cid_datafam_insts = adts'@@ -330,7 +331,7 @@ ; returnJustL $ InstD noExtField $ DataFamInstD { dfid_ext = noExtField- , dfid_inst = DataFamInstDecl { dfid_eqn = mkHsImplicitBndrs $+ , dfid_inst = DataFamInstDecl { dfid_eqn = FamEqn { feqn_ext = noExtField , feqn_tycon = tc' , feqn_bndrs = bndrs'@@ -350,7 +351,7 @@ , dd_cons = [con'], dd_derivs = derivs' } ; returnJustL $ InstD noExtField $ DataFamInstD { dfid_ext = noExtField- , dfid_inst = DataFamInstDecl { dfid_eqn = mkHsImplicitBndrs $+ , dfid_inst = DataFamInstDecl { dfid_eqn = FamEqn { feqn_ext = noExtField , feqn_tycon = tc' , feqn_bndrs = bndrs'@@ -386,18 +387,19 @@ = do { cxt' <- cvtContext funPrec cxt ; ds' <- traverse cvtDerivStrategy ds ; (L loc ty') <- cvtType ty- ; let inst_ty' = mkHsQualTy cxt loc cxt' $ L loc ty'+ ; let inst_ty' = L loc $ mkHsImplicitSigType $+ mkHsQualTy cxt loc cxt' $ L loc ty' ; returnJustL $ DerivD noExtField $ DerivDecl { deriv_ext =noExtField , deriv_strategy = ds'- , deriv_type = mkLHsSigWcType inst_ty'+ , deriv_type = mkHsWildCardBndrs inst_ty' , deriv_overlap_mode = Nothing } } cvtDec (TH.DefaultSigD nm typ) = do { nm' <- vNameL nm- ; ty' <- cvtType typ+ ; ty' <- cvtSigType typ ; returnJustL $ Hs.SigD noExtField- $ ClassOpSig noExtField True [nm'] (mkLHsSigType ty')}+ $ ClassOpSig noExtField True [nm'] ty'} cvtDec (TH.PatSynD nm args dir pat) = do { nm' <- cNameL nm@@ -424,7 +426,7 @@ cvtDec (TH.PatSynSigD nm ty) = do { nm' <- cNameL nm ; ty' <- cvtPatSynSigTy ty- ; returnJustL $ Hs.SigD noExtField $ PatSynSig noExtField [nm'] (mkLHsSigType ty')}+ ; returnJustL $ Hs.SigD noExtField $ PatSynSig noExtField [nm'] ty'} -- Implicit parameter bindings are handled in cvtLocalDecs and -- cvtImplicitParamBind. They are not allowed in any other scope, so@@ -436,25 +438,26 @@ cvtTySynEqn :: TySynEqn -> CvtM (LTyFamInstEqn GhcPs) cvtTySynEqn (TySynEqn mb_bndrs lhs rhs) = do { mb_bndrs' <- traverse (mapM cvt_tv) mb_bndrs+ ; let outer_bndrs = mkHsOuterFamEqnTyVarBndrs mb_bndrs' ; (head_ty, args) <- split_ty_app lhs ; case head_ty of ConT nm -> do { nm' <- tconNameL nm ; rhs' <- cvtType rhs ; let args' = map wrap_tyarg args- ; returnL $ mkHsImplicitBndrs+ ; returnL $ FamEqn { feqn_ext = noExtField , feqn_tycon = nm'- , feqn_bndrs = mb_bndrs'+ , feqn_bndrs = outer_bndrs , feqn_pats = args' , feqn_fixity = Prefix , feqn_rhs = rhs' } } InfixT t1 nm t2 -> do { nm' <- tconNameL nm ; args' <- mapM cvtType [t1,t2] ; rhs' <- cvtType rhs- ; returnL $ mkHsImplicitBndrs+ ; returnL $ FamEqn { feqn_ext = noExtField , feqn_tycon = nm'- , feqn_bndrs = mb_bndrs'+ , feqn_bndrs = outer_bndrs , feqn_pats = (map HsValArg args') ++ args , feqn_fixity = Hs.Infix@@ -497,19 +500,20 @@ cvt_datainst_hdr :: TH.Cxt -> Maybe [TH.TyVarBndr ()] -> TH.Type -> CvtM ( LHsContext GhcPs , Located RdrName- , Maybe [LHsTyVarBndr () GhcPs]+ , HsOuterFamEqnTyVarBndrs GhcPs , HsTyPats GhcPs) cvt_datainst_hdr cxt bndrs tys = do { cxt' <- cvtContext funPrec cxt ; bndrs' <- traverse (mapM cvt_tv) bndrs+ ; let outer_bndrs = mkHsOuterFamEqnTyVarBndrs bndrs' ; (head_ty, args) <- split_ty_app tys ; case head_ty of ConT nm -> do { nm' <- tconNameL nm ; let args' = map wrap_tyarg args- ; return (cxt', nm', bndrs', args') }+ ; return (cxt', nm', outer_bndrs, args') } InfixT t1 nm t2 -> do { nm' <- tconNameL nm ; args' <- mapM cvtType [t1,t2]- ; return (cxt', nm', bndrs',+ ; return (cxt', nm', outer_bndrs, ((map HsValArg args') ++ args)) } _ -> failWith $ text "Invalid type instance header:" <+> text (show tys) }@@ -601,13 +605,18 @@ add_forall :: [LHsTyVarBndr Hs.Specificity GhcPs] -> LHsContext GhcPs -> ConDecl GhcPs -> ConDecl GhcPs- add_forall tvs' cxt' con@(ConDeclGADT { con_qvars = qvars, con_mb_cxt = cxt })- = con { con_forall = noLoc $ not (null all_tvs)- , con_qvars = all_tvs+ add_forall tvs' cxt' con@(ConDeclGADT { con_bndrs = L l outer_bndrs, con_mb_cxt = cxt })+ = con { con_bndrs = L l outer_bndrs' , con_mb_cxt = add_cxt cxt' cxt } where- all_tvs = tvs' ++ qvars+ outer_bndrs'+ | null all_tvs = mkHsOuterImplicit+ | otherwise = mkHsOuterExplicit all_tvs + all_tvs = tvs' ++ outer_exp_tvs++ outer_exp_tvs = hsOuterExplicitBndrs outer_bndrs+ add_forall tvs' cxt' con@(ConDeclH98 { con_ex_tvs = ex_tvs, con_mb_cxt = cxt }) = con { con_forall = noLoc $ not (null all_tvs) , con_ex_tvs = all_tvs@@ -638,8 +647,7 @@ mk_gadt_decl names args res_ty = ConDeclGADT { con_g_ext = noExtField , con_names = names- , con_forall = noLoc False- , con_qvars = []+ , con_bndrs = noLoc mkHsOuterImplicit , con_mb_cxt = Nothing , con_g_args = args , con_res_ty = res_ty@@ -707,10 +715,10 @@ where mk_imp impspec = do { nm' <- vNameL nm- ; ty' <- cvtType ty+ ; ty' <- cvtSigType ty ; return (ForeignImport { fd_i_ext = noExtField , fd_name = nm'- , fd_sig_ty = mkLHsSigType ty'+ , fd_sig_ty = ty' , fd_fi = impspec }) } safety' = case safety of@@ -720,14 +728,14 @@ cvtForD (ExportF callconv as nm ty) = do { nm' <- vNameL nm- ; ty' <- cvtType ty+ ; ty' <- cvtSigType ty ; let e = CExport (noLoc (CExportStatic (SourceText as) (mkFastString as) (cvt_conv callconv))) (noLoc (SourceText as)) ; return $ ForeignExport { fd_e_ext = noExtField , fd_name = nm'- , fd_sig_ty = mkLHsSigType ty'+ , fd_sig_ty = ty' , fd_fe = e } } cvt_conv :: TH.Callconv -> CCallConv@@ -757,7 +765,7 @@ cvtPragmaD (SpecialiseP nm ty inline phases) = do { nm' <- vNameL nm- ; ty' <- cvtType ty+ ; ty' <- cvtSigType ty ; let src TH.NoInline = "{-# SPECIALISE NOINLINE" src TH.Inline = "{-# SPECIALISE INLINE" src TH.Inlinable = "{-# SPECIALISE INLINE"@@ -771,12 +779,12 @@ , inl_rule = Hs.FunLike , inl_act = cvtPhases phases dflt , inl_sat = Nothing }- ; returnJustL $ Hs.SigD noExtField $ SpecSig noExtField nm' [mkLHsSigType ty'] ip }+ ; returnJustL $ Hs.SigD noExtField $ SpecSig noExtField nm' [ty'] ip } cvtPragmaD (SpecialiseInstP ty)- = do { ty' <- cvtType ty+ = do { ty' <- cvtSigType ty ; returnJustL $ Hs.SigD noExtField $- SpecInstSig noExtField (SourceText "{-# SPECIALISE") (mkLHsSigType ty') }+ SpecInstSig noExtField (SourceText "{-# SPECIALISE") ty' } cvtPragmaD (RuleP nm ty_bndrs tm_bndrs lhs rhs phases) = do { let nm' = mkFastString nm@@ -1002,9 +1010,9 @@ ; cvtOpApp x'' s y } -- Note [Converting UInfix] cvt (ParensE e) = do { e' <- cvtl e; return $ HsPar noExtField e' }- cvt (SigE e t) = do { e' <- cvtl e; t' <- cvtType t+ cvt (SigE e t) = do { e' <- cvtl e; t' <- cvtSigType t ; let pe = parenthesizeHsExpr sigPrec e'- ; return $ ExprWithTySig noExtField pe (mkLHsSigWcType t') }+ ; return $ ExprWithTySig noExtField pe (mkHsWildCardBndrs t') } cvt (RecConE c flds) = do { c' <- cNameL c ; flds' <- mapM (cvtFld (mkFieldOcc . noLoc)) flds ; return $ mkRdrRecordCon c' (HsRecFields flds' Nothing) }@@ -1398,16 +1406,17 @@ cvtDerivClauseTys :: TH.Cxt -> CvtM (LDerivClauseTys GhcPs) cvtDerivClauseTys tys- = do { tys' <- mapM cvtType tys+ = do { tys' <- mapM cvtSigType tys -- Since TH.Cxt doesn't indicate the presence or absence of -- parentheses in a deriving clause, we have to choose between -- DctSingle and DctMulti somewhat arbitrarily. We opt to use DctMulti -- unless the TH.Cxt is a singleton list whose type is a bare type -- constructor with no arguments. ; case tys' of- [ty'@(L l (HsTyVar _ NotPromoted _))]- -> return $ L l $ DctSingle noExtField $ mkLHsSigType ty'- _ -> returnL $ DctMulti noExtField (map mkLHsSigType tys') }+ [ty'@(L l (HsSig { sig_bndrs = HsOuterImplicit{}+ , sig_body = L _ (HsTyVar _ NotPromoted _) }))]+ -> return $ L l $ DctSingle noExtField ty'+ _ -> returnL $ DctMulti noExtField tys' } cvtDerivClause :: TH.DerivClause -> CvtM (LHsDerivingClause GhcPs)@@ -1421,12 +1430,23 @@ cvtDerivStrategy TH.AnyclassStrategy = returnL Hs.AnyclassStrategy cvtDerivStrategy TH.NewtypeStrategy = returnL Hs.NewtypeStrategy cvtDerivStrategy (TH.ViaStrategy ty) = do- ty' <- cvtType ty- returnL $ Hs.ViaStrategy (mkLHsSigType ty')+ ty' <- cvtSigType ty+ returnL $ Hs.ViaStrategy ty' cvtType :: TH.Type -> CvtM (LHsType GhcPs) cvtType = cvtTypeKind "type" +cvtSigType :: TH.Type -> CvtM (LHsSigType GhcPs)+cvtSigType = cvtSigTypeKind "type"++-- | Convert a Template Haskell 'Type' to an 'LHsSigType'. To avoid duplicating+-- the logic in 'cvtTypeKind' here, we simply reuse 'cvtTypeKind' and perform+-- surgery on the 'LHsType' it returns to turn it into an 'LHsSigType'.+cvtSigTypeKind :: String -> TH.Type -> CvtM (LHsSigType GhcPs)+cvtSigTypeKind ty_str ty = do+ ty' <- cvtTypeKind ty_str ty+ pure $ hsTypeToHsSigType ty'+ cvtTypeKind :: String -> TH.Type -> CvtM (LHsType GhcPs) cvtTypeKind ty_str ty = do { (head_ty, tys') <- split_ty_app ty@@ -1726,6 +1746,9 @@ cvtKind :: TH.Kind -> CvtM (LHsKind GhcPs) cvtKind = cvtTypeKind "kind" +cvtSigKind :: TH.Kind -> CvtM (LHsSigType GhcPs)+cvtSigKind = cvtSigTypeKind "kind"+ -- | Convert Maybe Kind to a type family result signature. Used with data -- families where naming of the result is not possible (thus only kind or no -- signature is possible).@@ -1752,30 +1775,28 @@ ; annRHS' <- mapM tNameL annRHS ; returnL (Hs.InjectivityAnn annLHS' annRHS') } -cvtPatSynSigTy :: TH.Type -> CvtM (LHsType GhcPs)+cvtPatSynSigTy :: TH.Type -> CvtM (LHsSigType GhcPs) -- pattern synonym types are of peculiar shapes, which is why we treat -- them separately from regular types; -- see Note [Pattern synonym type signatures and Template Haskell] cvtPatSynSigTy (ForallT univs reqs (ForallT exis provs ty))- | null exis, null provs = cvtType (ForallT univs reqs ty)+ | null exis, null provs = cvtSigType (ForallT univs reqs ty) | null univs, null reqs = do { l <- getL ; ty' <- cvtType (ForallT exis provs ty)- ; return $ L l (HsQualTy { hst_ctxt = L l []+ ; return $ L l $ mkHsImplicitSigType+ $ L l (HsQualTy { hst_ctxt = L l [] , hst_xqual = noExtField , hst_body = ty' }) } | null reqs = do { l <- getL ; univs' <- cvtTvs univs ; ty' <- cvtType (ForallT exis provs ty)- ; let forTy = HsForAllTy- { hst_tele = mkHsForAllInvisTele univs'- , hst_xforall = noExtField- , hst_body = L l cxtTy }+ ; let forTy = mkHsExplicitSigType univs' $ L l cxtTy cxtTy = HsQualTy { hst_ctxt = L l [] , hst_xqual = noExtField , hst_body = ty' } ; return $ L l forTy }- | otherwise = cvtType (ForallT univs reqs (ForallT exis provs ty))-cvtPatSynSigTy ty = cvtType ty+ | otherwise = cvtSigType (ForallT univs reqs (ForallT exis provs ty))+cvtPatSynSigTy ty = cvtSigType ty ----------------------------------------------------------- cvtFixity :: TH.Fixity -> Hs.Fixity@@ -1858,6 +1879,9 @@ | otherwise = L loc $ HsQualTy { hst_xqual = noExtField , hst_ctxt = ctxt' , hst_body = ty }++mkHsOuterFamEqnTyVarBndrs :: Maybe [LHsTyVarBndr () GhcPs] -> HsOuterFamEqnTyVarBndrs GhcPs+mkHsOuterFamEqnTyVarBndrs = maybe mkHsOuterImplicit mkHsOuterExplicit -------------------------------------------------------------------- -- Turning Name back into RdrName
compiler/GHC/Unit/Finder.hs view
@@ -59,7 +59,7 @@ import GHC.Utils.Outputable as Outputable import GHC.Utils.Panic -import GHC.Runtime.Linker.Types+import GHC.Linker.Types import Data.IORef ( IORef, readIORef, atomicModifyIORef' ) import System.Directory
ghc-lib.cabal view
@@ -1,7 +1,7 @@ cabal-version: >=1.22 build-type: Simple name: ghc-lib-version: 0.20201101+version: 0.20201201 license: BSD3 license-file: LICENSE category: Development@@ -79,7 +79,8 @@ process >= 1 && < 1.7, hpc == 0.6.*, exceptions == 0.10.*,- ghc-lib-parser == 0.20201101+ parsec,+ ghc-lib-parser == 0.20201201 build-tools: alex >= 3.1, happy >= 1.19.4 other-extensions: BangPatterns@@ -165,6 +166,7 @@ GHC.Core.Map, GHC.Core.Multiplicity, GHC.Core.Opt.Arity,+ GHC.Core.Opt.CallerCC, GHC.Core.Opt.ConstantFold, GHC.Core.Opt.Monad, GHC.Core.Opt.OccurAnal,@@ -224,9 +226,16 @@ GHC.Exts.Heap.ClosureTypes, GHC.Exts.Heap.Closures, GHC.Exts.Heap.Constants,+ GHC.Exts.Heap.FFIClosures,+ GHC.Exts.Heap.FFIClosures_ProfilingDisabled,+ GHC.Exts.Heap.FFIClosures_ProfilingEnabled, GHC.Exts.Heap.InfoTable, GHC.Exts.Heap.InfoTable.Types, GHC.Exts.Heap.InfoTableProf,+ GHC.Exts.Heap.ProfInfo.PeekProfInfo,+ GHC.Exts.Heap.ProfInfo.PeekProfInfo_ProfilingDisabled,+ GHC.Exts.Heap.ProfInfo.PeekProfInfo_ProfilingEnabled,+ GHC.Exts.Heap.ProfInfo.Types, GHC.Exts.Heap.Utils, GHC.ForeignSrcLang, GHC.ForeignSrcLang.Type,@@ -250,6 +259,7 @@ GHC.LanguageExtensions, GHC.LanguageExtensions.Type, GHC.Lexeme,+ GHC.Linker.Types, GHC.Parser, GHC.Parser.Annotation, GHC.Parser.CharClass,@@ -261,8 +271,8 @@ GHC.Parser.PostProcess.Haddock, GHC.Parser.Types, GHC.Platform,+ GHC.Platform.AArch64, GHC.Platform.ARM,- GHC.Platform.ARM64, GHC.Platform.ArchOS, GHC.Platform.Constants, GHC.Platform.NoRegs,@@ -281,7 +291,6 @@ GHC.Runtime.Eval.Types, GHC.Runtime.Heap.Layout, GHC.Runtime.Interpreter.Types,- GHC.Runtime.Linker.Types, GHC.Serialized, GHC.Settings, GHC.Settings.Config,@@ -595,6 +604,14 @@ GHC.Iface.Tidy.StaticPtrTable GHC.Iface.UpdateIdInfos GHC.IfaceToCore+ GHC.Linker+ GHC.Linker.Dynamic+ GHC.Linker.ExtraObj+ GHC.Linker.Loader+ GHC.Linker.MacOS+ GHC.Linker.Static+ GHC.Linker.Unit+ GHC.Linker.Windows GHC.Llvm GHC.Llvm.MetaData GHC.Llvm.Ppr@@ -617,7 +634,6 @@ GHC.Runtime.Eval GHC.Runtime.Heap.Inspect GHC.Runtime.Interpreter- GHC.Runtime.Linker GHC.Runtime.Loader GHC.Settings.IO GHC.Settings.Utils@@ -653,7 +669,6 @@ GHC.SysTools GHC.SysTools.Ar GHC.SysTools.Elf- GHC.SysTools.ExtraObj GHC.SysTools.Info GHC.SysTools.Process GHC.SysTools.Tasks
ghc-lib/stage0/compiler/build/primop-can-fail.hs-incl view
@@ -211,6 +211,18 @@ primOpCanFail WriteOffAddrOp_Word16 = True primOpCanFail WriteOffAddrOp_Word32 = True primOpCanFail WriteOffAddrOp_Word64 = True+primOpCanFail InterlockedExchange_Addr = True+primOpCanFail InterlockedExchange_Word = True+primOpCanFail CasAddrOp_Addr = True+primOpCanFail CasAddrOp_Word = True+primOpCanFail FetchAddAddrOp_Word = True+primOpCanFail FetchSubAddrOp_Word = True+primOpCanFail FetchAndAddrOp_Word = True+primOpCanFail FetchNandAddrOp_Word = True+primOpCanFail FetchOrAddrOp_Word = True+primOpCanFail FetchXorAddrOp_Word = True+primOpCanFail AtomicReadAddrOp_Word = True+primOpCanFail AtomicWriteAddrOp_Word = True primOpCanFail AtomicModifyMutVar2Op = True primOpCanFail AtomicModifyMutVar_Op = True primOpCanFail RaiseOp = True
ghc-lib/stage0/compiler/build/primop-commutable.hs-incl view
@@ -11,9 +11,9 @@ commutableOp IntAddOp = True commutableOp IntMulOp = True commutableOp IntMulMayOfloOp = True-commutableOp AndIOp = True-commutableOp OrIOp = True-commutableOp XorIOp = True+commutableOp IntAndOp = True+commutableOp IntOrOp = True+commutableOp IntXorOp = True commutableOp IntAddCOp = True commutableOp IntEqOp = True commutableOp IntNeOp = True@@ -22,9 +22,9 @@ commutableOp WordAdd2Op = True commutableOp WordMulOp = True commutableOp WordMul2Op = True-commutableOp AndOp = True-commutableOp OrOp = True-commutableOp XorOp = True+commutableOp WordAndOp = True+commutableOp WordOrOp = True+commutableOp WordXorOp = True commutableOp DoubleEqOp = True commutableOp DoubleNeOp = True commutableOp DoubleAddOp = True
ghc-lib/stage0/compiler/build/primop-data-decl.hs-incl view
@@ -6,8 +6,8 @@ | CharLtOp | CharLeOp | OrdOp- | Int8Extend- | Int8Narrow+ | Int8ExtendOp+ | Int8NarrowOp | Int8NegOp | Int8AddOp | Int8SubOp@@ -21,8 +21,8 @@ | Int8LeOp | Int8LtOp | Int8NeOp- | Word8Extend- | Word8Narrow+ | Word8ExtendOp+ | Word8NarrowOp | Word8NotOp | Word8AddOp | Word8SubOp@@ -36,8 +36,8 @@ | Word8LeOp | Word8LtOp | Word8NeOp- | Int16Extend- | Int16Narrow+ | Int16ExtendOp+ | Int16NarrowOp | Int16NegOp | Int16AddOp | Int16SubOp@@ -51,8 +51,8 @@ | Int16LeOp | Int16LtOp | Int16NeOp- | Word16Extend- | Word16Narrow+ | Word16ExtendOp+ | Word16NarrowOp | Word16NotOp | Word16AddOp | Word16SubOp@@ -66,6 +66,10 @@ | Word16LeOp | Word16LtOp | Word16NeOp+ | Int32ExtendOp+ | Int32NarrowOp+ | Word32ExtendOp+ | Word32NarrowOp | IntAddOp | IntSubOp | IntMulOp@@ -74,10 +78,10 @@ | IntQuotOp | IntRemOp | IntQuotRemOp- | AndIOp- | OrIOp- | XorIOp- | NotIOp+ | IntAndOp+ | IntOrOp+ | IntXorOp+ | IntNotOp | IntNegOp | IntAddCOp | IntSubCOp@@ -93,9 +97,9 @@ | IntToDoubleOp | WordToFloatOp | WordToDoubleOp- | ISllOp- | ISraOp- | ISrlOp+ | IntSllOp+ | IntSraOp+ | IntSrlOp | WordAddOp | WordAddCOp | WordSubCOp@@ -107,12 +111,12 @@ | WordRemOp | WordQuotRemOp | WordQuotRem2Op- | AndOp- | OrOp- | XorOp- | NotOp- | SllOp- | SrlOp+ | WordAndOp+ | WordOrOp+ | WordXorOp+ | WordNotOp+ | WordSllOp+ | WordSrlOp | WordToIntOp | WordGtOp | WordGeOp@@ -457,9 +461,17 @@ | WriteOffAddrOp_Word32 | WriteOffAddrOp_Word64 | InterlockedExchange_Addr- | InterlockedExchange_Int- | AtomicCompareExchange_Int- | AtomicCompareExchange_Addr+ | InterlockedExchange_Word+ | CasAddrOp_Addr+ | CasAddrOp_Word+ | FetchAddAddrOp_Word+ | FetchSubAddrOp_Word+ | FetchAndAddrOp_Word+ | FetchNandAddrOp_Word+ | FetchOrAddrOp_Word+ | FetchXorAddrOp_Word+ | AtomicReadAddrOp_Word+ | AtomicWriteAddrOp_Word | NewMutVarOp | ReadMutVarOp | WriteMutVarOp
ghc-lib/stage0/compiler/build/primop-docs.hs-incl view
@@ -206,11 +206,11 @@ , ("atomicWriteIntArray#","Given an array and an offset in machine words, write an element. The\n index is assumed to be in bounds. Implies a full memory barrier.") , ("casIntArray#","Given an array, an offset in machine words, the expected old value, and\n the new value, perform an atomic compare and swap i.e. write the new\n value if the current value matches the provided old value. Returns\n the value of the element before the operation. Implies a full memory\n barrier.") , ("fetchAddIntArray#","Given an array, and offset in machine words, and a value to add,\n atomically add the value to the element. Returns the value of the\n element before the operation. Implies a full memory barrier.")- , ("fetchSubIntArray#","Given an array, and offset in machine words, and a value to subtract,\n atomically subtract the value to the element. Returns the value of\n the element before the operation. Implies a full memory barrier.")- , ("fetchAndIntArray#","Given an array, and offset in machine words, and a value to AND,\n atomically AND the value to the element. Returns the value of the\n element before the operation. Implies a full memory barrier.")- , ("fetchNandIntArray#","Given an array, and offset in machine words, and a value to NAND,\n atomically NAND the value to the element. Returns the value of the\n element before the operation. Implies a full memory barrier.")- , ("fetchOrIntArray#","Given an array, and offset in machine words, and a value to OR,\n atomically OR the value to the element. Returns the value of the\n element before the operation. Implies a full memory barrier.")- , ("fetchXorIntArray#","Given an array, and offset in machine words, and a value to XOR,\n atomically XOR the value to the element. Returns the value of the\n element before the operation. Implies a full memory barrier.")+ , ("fetchSubIntArray#","Given an array, and offset in machine words, and a value to subtract,\n atomically subtract the value from the element. Returns the value of\n the element before the operation. Implies a full memory barrier.")+ , ("fetchAndIntArray#","Given an array, and offset in machine words, and a value to AND,\n atomically AND the value into the element. Returns the value of the\n element before the operation. Implies a full memory barrier.")+ , ("fetchNandIntArray#","Given an array, and offset in machine words, and a value to NAND,\n atomically NAND the value into the element. Returns the value of the\n element before the operation. Implies a full memory barrier.")+ , ("fetchOrIntArray#","Given an array, and offset in machine words, and a value to OR,\n atomically OR the value into the element. Returns the value of the\n element before the operation. Implies a full memory barrier.")+ , ("fetchXorIntArray#","Given an array, and offset in machine words, and a value to XOR,\n atomically XOR the value into the element. Returns the value of the\n element before the operation. Implies a full memory barrier.") , ("newArrayArray#","Create a new mutable array of arrays with the specified number of elements,\n in the specified state thread, with each element recursively referring to the\n newly created array.") , ("unsafeFreezeArrayArray#","Make a mutable array of arrays immutable, without copying.") , ("sizeofArrayArray#","Return the number of elements in the array.")@@ -227,10 +227,18 @@ , ("indexWideCharOffAddr#","Reads 31-bit character; offset in 4-byte words.") , ("readCharOffAddr#","Reads 8-bit character; offset in bytes.") , ("readWideCharOffAddr#","Reads 31-bit character; offset in 4-byte words.")- , ("atomicExchangeAddr#","The atomic exchange operation. Atomically exchanges the value at the first address\n with the Addr# given as second argument. Implies a read barrier.")- , ("atomicExchangeInt#","The atomic exchange operation. Atomically exchanges the value at the address\n with the given value. Returns the old value. Implies a read barrier.")- , ("atomicCasInt#"," Compare and swap on a word-sized memory location.\n\n Use as atomicCasInt# location expected desired\n\n This version always returns the old value read. This follows the normal protocol for CAS operations (and matches the underlying instruction on most architectures).\n\n Implies a full memory barrier.")- , ("atomicCasAddr#"," Compare and swap on a word-sized memory location.\n\n Use as atomicCasAddr# location expected desired\n\n This version always returns the old value read. This follows the normal protocol for CAS operations (and matches the underlying instruction on most architectures).\n\n Implies a full memory barrier.")+ , ("atomicExchangeAddrAddr#","The atomic exchange operation. Atomically exchanges the value at the first address\n with the Addr# given as second argument. Implies a read barrier.")+ , ("atomicExchangeWordAddr#","The atomic exchange operation. Atomically exchanges the value at the address\n with the given value. Returns the old value. Implies a read barrier.")+ , ("atomicCasAddrAddr#"," Compare and swap on a word-sized memory location.\n\n Use as: \\s -> atomicCasAddrAddr# location expected desired s\n\n This version always returns the old value read. This follows the normal\n protocol for CAS operations (and matches the underlying instruction on\n most architectures).\n\n Implies a full memory barrier.")+ , ("atomicCasWordAddr#"," Compare and swap on a word-sized and aligned memory location.\n\n Use as: \\s -> atomicCasWordAddr# location expected desired s\n\n This version always returns the old value read. This follows the normal\n protocol for CAS operations (and matches the underlying instruction on\n most architectures).\n\n Implies a full memory barrier.")+ , ("fetchAddWordAddr#","Given an address, and a value to add,\n atomically add the value to the element. Returns the value of the\n element before the operation. Implies a full memory barrier.")+ , ("fetchSubWordAddr#","Given an address, and a value to subtract,\n atomically subtract the value from the element. Returns the value of\n the element before the operation. Implies a full memory barrier.")+ , ("fetchAndWordAddr#","Given an address, and a value to AND,\n atomically AND the value into the element. Returns the value of the\n element before the operation. Implies a full memory barrier.")+ , ("fetchNandWordAddr#","Given an address, and a value to NAND,\n atomically NAND the value into the element. Returns the value of the\n element before the operation. Implies a full memory barrier.")+ , ("fetchOrWordAddr#","Given an address, and a value to OR,\n atomically OR the value into the element. Returns the value of the\n element before the operation. Implies a full memory barrier.")+ , ("fetchXorWordAddr#","Given an address, and a value to XOR,\n atomically XOR the value into the element. Returns the value of the\n element before the operation. Implies a full memory barrier.")+ , ("atomicReadWordAddr#","Given an address, read a machine word. Implies a full memory barrier.")+ , ("atomicWriteWordAddr#","Given an address, write a machine word. Implies a full memory barrier.") , ("MutVar#","A @MutVar\\#@ behaves like a single-element mutable array.") , ("newMutVar#","Create @MutVar\\#@ with specified initial value in specified state thread.") , ("readMutVar#","Read contents of @MutVar\\#@. Result is not yet evaluated.")
ghc-lib/stage0/compiler/build/primop-has-side-effects.hs-incl view
@@ -149,9 +149,17 @@ primOpHasSideEffects WriteOffAddrOp_Word32 = True primOpHasSideEffects WriteOffAddrOp_Word64 = True primOpHasSideEffects InterlockedExchange_Addr = True-primOpHasSideEffects InterlockedExchange_Int = True-primOpHasSideEffects AtomicCompareExchange_Int = True-primOpHasSideEffects AtomicCompareExchange_Addr = True+primOpHasSideEffects InterlockedExchange_Word = True+primOpHasSideEffects CasAddrOp_Addr = True+primOpHasSideEffects CasAddrOp_Word = True+primOpHasSideEffects FetchAddAddrOp_Word = True+primOpHasSideEffects FetchSubAddrOp_Word = True+primOpHasSideEffects FetchAndAddrOp_Word = True+primOpHasSideEffects FetchNandAddrOp_Word = True+primOpHasSideEffects FetchOrAddrOp_Word = True+primOpHasSideEffects FetchXorAddrOp_Word = True+primOpHasSideEffects AtomicReadAddrOp_Word = True+primOpHasSideEffects AtomicWriteAddrOp_Word = True primOpHasSideEffects NewMutVarOp = True primOpHasSideEffects ReadMutVarOp = True primOpHasSideEffects WriteMutVarOp = True
ghc-lib/stage0/compiler/build/primop-list.hs-incl view
@@ -5,8 +5,8 @@ , CharLtOp , CharLeOp , OrdOp- , Int8Extend- , Int8Narrow+ , Int8ExtendOp+ , Int8NarrowOp , Int8NegOp , Int8AddOp , Int8SubOp@@ -20,8 +20,8 @@ , Int8LeOp , Int8LtOp , Int8NeOp- , Word8Extend- , Word8Narrow+ , Word8ExtendOp+ , Word8NarrowOp , Word8NotOp , Word8AddOp , Word8SubOp@@ -35,8 +35,8 @@ , Word8LeOp , Word8LtOp , Word8NeOp- , Int16Extend- , Int16Narrow+ , Int16ExtendOp+ , Int16NarrowOp , Int16NegOp , Int16AddOp , Int16SubOp@@ -50,8 +50,8 @@ , Int16LeOp , Int16LtOp , Int16NeOp- , Word16Extend- , Word16Narrow+ , Word16ExtendOp+ , Word16NarrowOp , Word16NotOp , Word16AddOp , Word16SubOp@@ -65,6 +65,10 @@ , Word16LeOp , Word16LtOp , Word16NeOp+ , Int32ExtendOp+ , Int32NarrowOp+ , Word32ExtendOp+ , Word32NarrowOp , IntAddOp , IntSubOp , IntMulOp@@ -73,10 +77,10 @@ , IntQuotOp , IntRemOp , IntQuotRemOp- , AndIOp- , OrIOp- , XorIOp- , NotIOp+ , IntAndOp+ , IntOrOp+ , IntXorOp+ , IntNotOp , IntNegOp , IntAddCOp , IntSubCOp@@ -92,9 +96,9 @@ , IntToDoubleOp , WordToFloatOp , WordToDoubleOp- , ISllOp- , ISraOp- , ISrlOp+ , IntSllOp+ , IntSraOp+ , IntSrlOp , WordAddOp , WordAddCOp , WordSubCOp@@ -106,12 +110,12 @@ , WordRemOp , WordQuotRemOp , WordQuotRem2Op- , AndOp- , OrOp- , XorOp- , NotOp- , SllOp- , SrlOp+ , WordAndOp+ , WordOrOp+ , WordXorOp+ , WordNotOp+ , WordSllOp+ , WordSrlOp , WordToIntOp , WordGtOp , WordGeOp@@ -456,9 +460,17 @@ , WriteOffAddrOp_Word32 , WriteOffAddrOp_Word64 , InterlockedExchange_Addr- , InterlockedExchange_Int- , AtomicCompareExchange_Int- , AtomicCompareExchange_Addr+ , InterlockedExchange_Word+ , CasAddrOp_Addr+ , CasAddrOp_Word+ , FetchAddAddrOp_Word+ , FetchSubAddrOp_Word+ , FetchAndAddrOp_Word+ , FetchNandAddrOp_Word+ , FetchOrAddrOp_Word+ , FetchXorAddrOp_Word+ , AtomicReadAddrOp_Word+ , AtomicWriteAddrOp_Word , NewMutVarOp , ReadMutVarOp , WriteMutVarOp
ghc-lib/stage0/compiler/build/primop-primop-info.hs-incl view
@@ -5,8 +5,8 @@ primOpInfo CharLtOp = mkCompare (fsLit "ltChar#") charPrimTy primOpInfo CharLeOp = mkCompare (fsLit "leChar#") charPrimTy primOpInfo OrdOp = mkGenPrimOp (fsLit "ord#") [] [charPrimTy] (intPrimTy)-primOpInfo Int8Extend = mkGenPrimOp (fsLit "extendInt8#") [] [int8PrimTy] (intPrimTy)-primOpInfo Int8Narrow = mkGenPrimOp (fsLit "narrowInt8#") [] [intPrimTy] (int8PrimTy)+primOpInfo Int8ExtendOp = mkGenPrimOp (fsLit "extendInt8#") [] [int8PrimTy] (intPrimTy)+primOpInfo Int8NarrowOp = mkGenPrimOp (fsLit "narrowInt8#") [] [intPrimTy] (int8PrimTy) primOpInfo Int8NegOp = mkGenPrimOp (fsLit "negateInt8#") [] [int8PrimTy] (int8PrimTy) primOpInfo Int8AddOp = mkGenPrimOp (fsLit "plusInt8#") [] [int8PrimTy, int8PrimTy] (int8PrimTy) primOpInfo Int8SubOp = mkGenPrimOp (fsLit "subInt8#") [] [int8PrimTy, int8PrimTy] (int8PrimTy)@@ -20,8 +20,8 @@ primOpInfo Int8LeOp = mkCompare (fsLit "leInt8#") int8PrimTy primOpInfo Int8LtOp = mkCompare (fsLit "ltInt8#") int8PrimTy primOpInfo Int8NeOp = mkCompare (fsLit "neInt8#") int8PrimTy-primOpInfo Word8Extend = mkGenPrimOp (fsLit "extendWord8#") [] [word8PrimTy] (wordPrimTy)-primOpInfo Word8Narrow = mkGenPrimOp (fsLit "narrowWord8#") [] [wordPrimTy] (word8PrimTy)+primOpInfo Word8ExtendOp = mkGenPrimOp (fsLit "extendWord8#") [] [word8PrimTy] (wordPrimTy)+primOpInfo Word8NarrowOp = mkGenPrimOp (fsLit "narrowWord8#") [] [wordPrimTy] (word8PrimTy) primOpInfo Word8NotOp = mkGenPrimOp (fsLit "notWord8#") [] [word8PrimTy] (word8PrimTy) primOpInfo Word8AddOp = mkGenPrimOp (fsLit "plusWord8#") [] [word8PrimTy, word8PrimTy] (word8PrimTy) primOpInfo Word8SubOp = mkGenPrimOp (fsLit "subWord8#") [] [word8PrimTy, word8PrimTy] (word8PrimTy)@@ -35,8 +35,8 @@ primOpInfo Word8LeOp = mkCompare (fsLit "leWord8#") word8PrimTy primOpInfo Word8LtOp = mkCompare (fsLit "ltWord8#") word8PrimTy primOpInfo Word8NeOp = mkCompare (fsLit "neWord8#") word8PrimTy-primOpInfo Int16Extend = mkGenPrimOp (fsLit "extendInt16#") [] [int16PrimTy] (intPrimTy)-primOpInfo Int16Narrow = mkGenPrimOp (fsLit "narrowInt16#") [] [intPrimTy] (int16PrimTy)+primOpInfo Int16ExtendOp = mkGenPrimOp (fsLit "extendInt16#") [] [int16PrimTy] (intPrimTy)+primOpInfo Int16NarrowOp = mkGenPrimOp (fsLit "narrowInt16#") [] [intPrimTy] (int16PrimTy) primOpInfo Int16NegOp = mkGenPrimOp (fsLit "negateInt16#") [] [int16PrimTy] (int16PrimTy) primOpInfo Int16AddOp = mkGenPrimOp (fsLit "plusInt16#") [] [int16PrimTy, int16PrimTy] (int16PrimTy) primOpInfo Int16SubOp = mkGenPrimOp (fsLit "subInt16#") [] [int16PrimTy, int16PrimTy] (int16PrimTy)@@ -50,8 +50,8 @@ primOpInfo Int16LeOp = mkCompare (fsLit "leInt16#") int16PrimTy primOpInfo Int16LtOp = mkCompare (fsLit "ltInt16#") int16PrimTy primOpInfo Int16NeOp = mkCompare (fsLit "neInt16#") int16PrimTy-primOpInfo Word16Extend = mkGenPrimOp (fsLit "extendWord16#") [] [word16PrimTy] (wordPrimTy)-primOpInfo Word16Narrow = mkGenPrimOp (fsLit "narrowWord16#") [] [wordPrimTy] (word16PrimTy)+primOpInfo Word16ExtendOp = mkGenPrimOp (fsLit "extendWord16#") [] [word16PrimTy] (wordPrimTy)+primOpInfo Word16NarrowOp = mkGenPrimOp (fsLit "narrowWord16#") [] [wordPrimTy] (word16PrimTy) primOpInfo Word16NotOp = mkGenPrimOp (fsLit "notWord16#") [] [word16PrimTy] (word16PrimTy) primOpInfo Word16AddOp = mkGenPrimOp (fsLit "plusWord16#") [] [word16PrimTy, word16PrimTy] (word16PrimTy) primOpInfo Word16SubOp = mkGenPrimOp (fsLit "subWord16#") [] [word16PrimTy, word16PrimTy] (word16PrimTy)@@ -65,6 +65,10 @@ primOpInfo Word16LeOp = mkCompare (fsLit "leWord16#") word16PrimTy primOpInfo Word16LtOp = mkCompare (fsLit "ltWord16#") word16PrimTy primOpInfo Word16NeOp = mkCompare (fsLit "neWord16#") word16PrimTy+primOpInfo Int32ExtendOp = mkGenPrimOp (fsLit "extendInt32#") [] [int32PrimTy] (intPrimTy)+primOpInfo Int32NarrowOp = mkGenPrimOp (fsLit "narrowInt32#") [] [intPrimTy] (int32PrimTy)+primOpInfo Word32ExtendOp = mkGenPrimOp (fsLit "extendWord32#") [] [word32PrimTy] (wordPrimTy)+primOpInfo Word32NarrowOp = mkGenPrimOp (fsLit "narrowWord32#") [] [wordPrimTy] (word32PrimTy) primOpInfo IntAddOp = mkGenPrimOp (fsLit "+#") [] [intPrimTy, intPrimTy] (intPrimTy) primOpInfo IntSubOp = mkGenPrimOp (fsLit "-#") [] [intPrimTy, intPrimTy] (intPrimTy) primOpInfo IntMulOp = mkGenPrimOp (fsLit "*#") [] [intPrimTy, intPrimTy] (intPrimTy)@@ -73,10 +77,10 @@ primOpInfo IntQuotOp = mkGenPrimOp (fsLit "quotInt#") [] [intPrimTy, intPrimTy] (intPrimTy) primOpInfo IntRemOp = mkGenPrimOp (fsLit "remInt#") [] [intPrimTy, intPrimTy] (intPrimTy) primOpInfo IntQuotRemOp = mkGenPrimOp (fsLit "quotRemInt#") [] [intPrimTy, intPrimTy] ((mkTupleTy Unboxed [intPrimTy, intPrimTy]))-primOpInfo AndIOp = mkGenPrimOp (fsLit "andI#") [] [intPrimTy, intPrimTy] (intPrimTy)-primOpInfo OrIOp = mkGenPrimOp (fsLit "orI#") [] [intPrimTy, intPrimTy] (intPrimTy)-primOpInfo XorIOp = mkGenPrimOp (fsLit "xorI#") [] [intPrimTy, intPrimTy] (intPrimTy)-primOpInfo NotIOp = mkGenPrimOp (fsLit "notI#") [] [intPrimTy] (intPrimTy)+primOpInfo IntAndOp = mkGenPrimOp (fsLit "andI#") [] [intPrimTy, intPrimTy] (intPrimTy)+primOpInfo IntOrOp = mkGenPrimOp (fsLit "orI#") [] [intPrimTy, intPrimTy] (intPrimTy)+primOpInfo IntXorOp = mkGenPrimOp (fsLit "xorI#") [] [intPrimTy, intPrimTy] (intPrimTy)+primOpInfo IntNotOp = mkGenPrimOp (fsLit "notI#") [] [intPrimTy] (intPrimTy) primOpInfo IntNegOp = mkGenPrimOp (fsLit "negateInt#") [] [intPrimTy] (intPrimTy) primOpInfo IntAddCOp = mkGenPrimOp (fsLit "addIntC#") [] [intPrimTy, intPrimTy] ((mkTupleTy Unboxed [intPrimTy, intPrimTy])) primOpInfo IntSubCOp = mkGenPrimOp (fsLit "subIntC#") [] [intPrimTy, intPrimTy] ((mkTupleTy Unboxed [intPrimTy, intPrimTy]))@@ -92,9 +96,9 @@ primOpInfo IntToDoubleOp = mkGenPrimOp (fsLit "int2Double#") [] [intPrimTy] (doublePrimTy) primOpInfo WordToFloatOp = mkGenPrimOp (fsLit "word2Float#") [] [wordPrimTy] (floatPrimTy) primOpInfo WordToDoubleOp = mkGenPrimOp (fsLit "word2Double#") [] [wordPrimTy] (doublePrimTy)-primOpInfo ISllOp = mkGenPrimOp (fsLit "uncheckedIShiftL#") [] [intPrimTy, intPrimTy] (intPrimTy)-primOpInfo ISraOp = mkGenPrimOp (fsLit "uncheckedIShiftRA#") [] [intPrimTy, intPrimTy] (intPrimTy)-primOpInfo ISrlOp = mkGenPrimOp (fsLit "uncheckedIShiftRL#") [] [intPrimTy, intPrimTy] (intPrimTy)+primOpInfo IntSllOp = mkGenPrimOp (fsLit "uncheckedIShiftL#") [] [intPrimTy, intPrimTy] (intPrimTy)+primOpInfo IntSraOp = mkGenPrimOp (fsLit "uncheckedIShiftRA#") [] [intPrimTy, intPrimTy] (intPrimTy)+primOpInfo IntSrlOp = mkGenPrimOp (fsLit "uncheckedIShiftRL#") [] [intPrimTy, intPrimTy] (intPrimTy) primOpInfo WordAddOp = mkGenPrimOp (fsLit "plusWord#") [] [wordPrimTy, wordPrimTy] (wordPrimTy) primOpInfo WordAddCOp = mkGenPrimOp (fsLit "addWordC#") [] [wordPrimTy, wordPrimTy] ((mkTupleTy Unboxed [wordPrimTy, intPrimTy])) primOpInfo WordSubCOp = mkGenPrimOp (fsLit "subWordC#") [] [wordPrimTy, wordPrimTy] ((mkTupleTy Unboxed [wordPrimTy, intPrimTy]))@@ -106,12 +110,12 @@ primOpInfo WordRemOp = mkGenPrimOp (fsLit "remWord#") [] [wordPrimTy, wordPrimTy] (wordPrimTy) primOpInfo WordQuotRemOp = mkGenPrimOp (fsLit "quotRemWord#") [] [wordPrimTy, wordPrimTy] ((mkTupleTy Unboxed [wordPrimTy, wordPrimTy])) primOpInfo WordQuotRem2Op = mkGenPrimOp (fsLit "quotRemWord2#") [] [wordPrimTy, wordPrimTy, wordPrimTy] ((mkTupleTy Unboxed [wordPrimTy, wordPrimTy]))-primOpInfo AndOp = mkGenPrimOp (fsLit "and#") [] [wordPrimTy, wordPrimTy] (wordPrimTy)-primOpInfo OrOp = mkGenPrimOp (fsLit "or#") [] [wordPrimTy, wordPrimTy] (wordPrimTy)-primOpInfo XorOp = mkGenPrimOp (fsLit "xor#") [] [wordPrimTy, wordPrimTy] (wordPrimTy)-primOpInfo NotOp = mkGenPrimOp (fsLit "not#") [] [wordPrimTy] (wordPrimTy)-primOpInfo SllOp = mkGenPrimOp (fsLit "uncheckedShiftL#") [] [wordPrimTy, intPrimTy] (wordPrimTy)-primOpInfo SrlOp = mkGenPrimOp (fsLit "uncheckedShiftRL#") [] [wordPrimTy, intPrimTy] (wordPrimTy)+primOpInfo WordAndOp = mkGenPrimOp (fsLit "and#") [] [wordPrimTy, wordPrimTy] (wordPrimTy)+primOpInfo WordOrOp = mkGenPrimOp (fsLit "or#") [] [wordPrimTy, wordPrimTy] (wordPrimTy)+primOpInfo WordXorOp = mkGenPrimOp (fsLit "xor#") [] [wordPrimTy, wordPrimTy] (wordPrimTy)+primOpInfo WordNotOp = mkGenPrimOp (fsLit "not#") [] [wordPrimTy] (wordPrimTy)+primOpInfo WordSllOp = mkGenPrimOp (fsLit "uncheckedShiftL#") [] [wordPrimTy, intPrimTy] (wordPrimTy)+primOpInfo WordSrlOp = mkGenPrimOp (fsLit "uncheckedShiftRL#") [] [wordPrimTy, intPrimTy] (wordPrimTy) primOpInfo WordToIntOp = mkGenPrimOp (fsLit "word2Int#") [] [wordPrimTy] (intPrimTy) primOpInfo WordGtOp = mkCompare (fsLit "gtWord#") wordPrimTy primOpInfo WordGeOp = mkCompare (fsLit "geWord#") wordPrimTy@@ -455,10 +459,18 @@ primOpInfo WriteOffAddrOp_Word16 = mkGenPrimOp (fsLit "writeWord16OffAddr#") [deltaTyVar] [addrPrimTy, intPrimTy, wordPrimTy, mkStatePrimTy deltaTy] (mkStatePrimTy deltaTy) primOpInfo WriteOffAddrOp_Word32 = mkGenPrimOp (fsLit "writeWord32OffAddr#") [deltaTyVar] [addrPrimTy, intPrimTy, wordPrimTy, mkStatePrimTy deltaTy] (mkStatePrimTy deltaTy) primOpInfo WriteOffAddrOp_Word64 = mkGenPrimOp (fsLit "writeWord64OffAddr#") [deltaTyVar] [addrPrimTy, intPrimTy, wordPrimTy, mkStatePrimTy deltaTy] (mkStatePrimTy deltaTy)-primOpInfo InterlockedExchange_Addr = mkGenPrimOp (fsLit "atomicExchangeAddr#") [deltaTyVar] [addrPrimTy, addrPrimTy, mkStatePrimTy deltaTy] ((mkTupleTy Unboxed [mkStatePrimTy deltaTy, addrPrimTy]))-primOpInfo InterlockedExchange_Int = mkGenPrimOp (fsLit "atomicExchangeInt#") [deltaTyVar] [addrPrimTy, intPrimTy, mkStatePrimTy deltaTy] ((mkTupleTy Unboxed [mkStatePrimTy deltaTy, intPrimTy]))-primOpInfo AtomicCompareExchange_Int = mkGenPrimOp (fsLit "atomicCasInt#") [deltaTyVar] [addrPrimTy, intPrimTy, intPrimTy, mkStatePrimTy deltaTy] ((mkTupleTy Unboxed [mkStatePrimTy deltaTy, intPrimTy]))-primOpInfo AtomicCompareExchange_Addr = mkGenPrimOp (fsLit "atomicCasAddr#") [deltaTyVar] [addrPrimTy, addrPrimTy, addrPrimTy, mkStatePrimTy deltaTy] ((mkTupleTy Unboxed [mkStatePrimTy deltaTy, addrPrimTy]))+primOpInfo InterlockedExchange_Addr = mkGenPrimOp (fsLit "atomicExchangeAddrAddr#") [deltaTyVar] [addrPrimTy, addrPrimTy, mkStatePrimTy deltaTy] ((mkTupleTy Unboxed [mkStatePrimTy deltaTy, addrPrimTy]))+primOpInfo InterlockedExchange_Word = mkGenPrimOp (fsLit "atomicExchangeWordAddr#") [deltaTyVar] [addrPrimTy, wordPrimTy, mkStatePrimTy deltaTy] ((mkTupleTy Unboxed [mkStatePrimTy deltaTy, wordPrimTy]))+primOpInfo CasAddrOp_Addr = mkGenPrimOp (fsLit "atomicCasAddrAddr#") [deltaTyVar] [addrPrimTy, addrPrimTy, addrPrimTy, mkStatePrimTy deltaTy] ((mkTupleTy Unboxed [mkStatePrimTy deltaTy, addrPrimTy]))+primOpInfo CasAddrOp_Word = mkGenPrimOp (fsLit "atomicCasWordAddr#") [deltaTyVar] [addrPrimTy, wordPrimTy, wordPrimTy, mkStatePrimTy deltaTy] ((mkTupleTy Unboxed [mkStatePrimTy deltaTy, wordPrimTy]))+primOpInfo FetchAddAddrOp_Word = mkGenPrimOp (fsLit "fetchAddWordAddr#") [deltaTyVar] [addrPrimTy, wordPrimTy, mkStatePrimTy deltaTy] ((mkTupleTy Unboxed [mkStatePrimTy deltaTy, wordPrimTy]))+primOpInfo FetchSubAddrOp_Word = mkGenPrimOp (fsLit "fetchSubWordAddr#") [deltaTyVar] [addrPrimTy, wordPrimTy, mkStatePrimTy deltaTy] ((mkTupleTy Unboxed [mkStatePrimTy deltaTy, wordPrimTy]))+primOpInfo FetchAndAddrOp_Word = mkGenPrimOp (fsLit "fetchAndWordAddr#") [deltaTyVar] [addrPrimTy, wordPrimTy, mkStatePrimTy deltaTy] ((mkTupleTy Unboxed [mkStatePrimTy deltaTy, wordPrimTy]))+primOpInfo FetchNandAddrOp_Word = mkGenPrimOp (fsLit "fetchNandWordAddr#") [deltaTyVar] [addrPrimTy, wordPrimTy, mkStatePrimTy deltaTy] ((mkTupleTy Unboxed [mkStatePrimTy deltaTy, wordPrimTy]))+primOpInfo FetchOrAddrOp_Word = mkGenPrimOp (fsLit "fetchOrWordAddr#") [deltaTyVar] [addrPrimTy, wordPrimTy, mkStatePrimTy deltaTy] ((mkTupleTy Unboxed [mkStatePrimTy deltaTy, wordPrimTy]))+primOpInfo FetchXorAddrOp_Word = mkGenPrimOp (fsLit "fetchXorWordAddr#") [deltaTyVar] [addrPrimTy, wordPrimTy, mkStatePrimTy deltaTy] ((mkTupleTy Unboxed [mkStatePrimTy deltaTy, wordPrimTy]))+primOpInfo AtomicReadAddrOp_Word = mkGenPrimOp (fsLit "atomicReadWordAddr#") [deltaTyVar] [addrPrimTy, mkStatePrimTy deltaTy] ((mkTupleTy Unboxed [mkStatePrimTy deltaTy, wordPrimTy]))+primOpInfo AtomicWriteAddrOp_Word = mkGenPrimOp (fsLit "atomicWriteWordAddr#") [deltaTyVar] [addrPrimTy, wordPrimTy, mkStatePrimTy deltaTy] (mkStatePrimTy deltaTy) primOpInfo NewMutVarOp = mkGenPrimOp (fsLit "newMutVar#") [alphaTyVar, deltaTyVar] [alphaTy, mkStatePrimTy deltaTy] ((mkTupleTy Unboxed [mkStatePrimTy deltaTy, mkMutVarPrimTy deltaTy alphaTy])) primOpInfo ReadMutVarOp = mkGenPrimOp (fsLit "readMutVar#") [deltaTyVar, alphaTyVar] [mkMutVarPrimTy deltaTy alphaTy, mkStatePrimTy deltaTy] ((mkTupleTy Unboxed [mkStatePrimTy deltaTy, alphaTy])) primOpInfo WriteMutVarOp = mkGenPrimOp (fsLit "writeMutVar#") [deltaTyVar, alphaTyVar] [mkMutVarPrimTy deltaTy alphaTy, alphaTy, mkStatePrimTy deltaTy] (mkStatePrimTy deltaTy)
ghc-lib/stage0/compiler/build/primop-strictness.hs-incl view
@@ -3,10 +3,10 @@ , topDmd] topDiv primOpStrictness RaiseOp = \ _arity -> mkClosedStrictSig [topDmd] botDiv primOpStrictness RaiseIOOp = \ _arity -> mkClosedStrictSig [topDmd, topDmd] exnDiv -primOpStrictness MaskAsyncExceptionsOp = \ _arity -> mkClosedStrictSig [strictApply1Dmd,topDmd] topDiv -primOpStrictness MaskUninterruptibleOp = \ _arity -> mkClosedStrictSig [strictApply1Dmd,topDmd] topDiv -primOpStrictness UnmaskAsyncExceptionsOp = \ _arity -> mkClosedStrictSig [strictApply1Dmd,topDmd] topDiv -primOpStrictness AtomicallyOp = \ _arity -> mkClosedStrictSig [strictApply1Dmd,topDmd] topDiv +primOpStrictness MaskAsyncExceptionsOp = \ _arity -> mkClosedStrictSig [strictOnceApply1Dmd,topDmd] topDiv +primOpStrictness MaskUninterruptibleOp = \ _arity -> mkClosedStrictSig [strictOnceApply1Dmd,topDmd] topDiv +primOpStrictness UnmaskAsyncExceptionsOp = \ _arity -> mkClosedStrictSig [strictOnceApply1Dmd,topDmd] topDiv +primOpStrictness AtomicallyOp = \ _arity -> mkClosedStrictSig [strictManyApply1Dmd,topDmd] topDiv primOpStrictness RetryOp = \ _arity -> mkClosedStrictSig [topDmd] botDiv primOpStrictness CatchRetryOp = \ _arity -> mkClosedStrictSig [ lazyApply1Dmd , lazyApply1Dmd@@ -15,8 +15,4 @@ , lazyApply2Dmd , topDmd ] topDiv primOpStrictness DataToTagOp = \ _arity -> mkClosedStrictSig [evalDmd] topDiv -primOpStrictness PrefetchValueOp3 = \ _arity -> mkClosedStrictSig [botDmd, topDmd] topDiv -primOpStrictness PrefetchValueOp2 = \ _arity -> mkClosedStrictSig [botDmd, topDmd] topDiv -primOpStrictness PrefetchValueOp1 = \ _arity -> mkClosedStrictSig [botDmd, topDmd] topDiv -primOpStrictness PrefetchValueOp0 = \ _arity -> mkClosedStrictSig [botDmd, topDmd] topDiv primOpStrictness _ = \ arity -> mkClosedStrictSig (replicate arity topDmd) topDiv
ghc-lib/stage0/compiler/build/primop-tag.hs-incl view
@@ -1,1215 +1,1227 @@ maxPrimOpTag :: Int-maxPrimOpTag = 1212-primOpTag :: PrimOp -> Int-primOpTag CharGtOp = 1-primOpTag CharGeOp = 2-primOpTag CharEqOp = 3-primOpTag CharNeOp = 4-primOpTag CharLtOp = 5-primOpTag CharLeOp = 6-primOpTag OrdOp = 7-primOpTag Int8Extend = 8-primOpTag Int8Narrow = 9-primOpTag Int8NegOp = 10-primOpTag Int8AddOp = 11-primOpTag Int8SubOp = 12-primOpTag Int8MulOp = 13-primOpTag Int8QuotOp = 14-primOpTag Int8RemOp = 15-primOpTag Int8QuotRemOp = 16-primOpTag Int8EqOp = 17-primOpTag Int8GeOp = 18-primOpTag Int8GtOp = 19-primOpTag Int8LeOp = 20-primOpTag Int8LtOp = 21-primOpTag Int8NeOp = 22-primOpTag Word8Extend = 23-primOpTag Word8Narrow = 24-primOpTag Word8NotOp = 25-primOpTag Word8AddOp = 26-primOpTag Word8SubOp = 27-primOpTag Word8MulOp = 28-primOpTag Word8QuotOp = 29-primOpTag Word8RemOp = 30-primOpTag Word8QuotRemOp = 31-primOpTag Word8EqOp = 32-primOpTag Word8GeOp = 33-primOpTag Word8GtOp = 34-primOpTag Word8LeOp = 35-primOpTag Word8LtOp = 36-primOpTag Word8NeOp = 37-primOpTag Int16Extend = 38-primOpTag Int16Narrow = 39-primOpTag Int16NegOp = 40-primOpTag Int16AddOp = 41-primOpTag Int16SubOp = 42-primOpTag Int16MulOp = 43-primOpTag Int16QuotOp = 44-primOpTag Int16RemOp = 45-primOpTag Int16QuotRemOp = 46-primOpTag Int16EqOp = 47-primOpTag Int16GeOp = 48-primOpTag Int16GtOp = 49-primOpTag Int16LeOp = 50-primOpTag Int16LtOp = 51-primOpTag Int16NeOp = 52-primOpTag Word16Extend = 53-primOpTag Word16Narrow = 54-primOpTag Word16NotOp = 55-primOpTag Word16AddOp = 56-primOpTag Word16SubOp = 57-primOpTag Word16MulOp = 58-primOpTag Word16QuotOp = 59-primOpTag Word16RemOp = 60-primOpTag Word16QuotRemOp = 61-primOpTag Word16EqOp = 62-primOpTag Word16GeOp = 63-primOpTag Word16GtOp = 64-primOpTag Word16LeOp = 65-primOpTag Word16LtOp = 66-primOpTag Word16NeOp = 67-primOpTag IntAddOp = 68-primOpTag IntSubOp = 69-primOpTag IntMulOp = 70-primOpTag IntMul2Op = 71-primOpTag IntMulMayOfloOp = 72-primOpTag IntQuotOp = 73-primOpTag IntRemOp = 74-primOpTag IntQuotRemOp = 75-primOpTag AndIOp = 76-primOpTag OrIOp = 77-primOpTag XorIOp = 78-primOpTag NotIOp = 79-primOpTag IntNegOp = 80-primOpTag IntAddCOp = 81-primOpTag IntSubCOp = 82-primOpTag IntGtOp = 83-primOpTag IntGeOp = 84-primOpTag IntEqOp = 85-primOpTag IntNeOp = 86-primOpTag IntLtOp = 87-primOpTag IntLeOp = 88-primOpTag ChrOp = 89-primOpTag IntToWordOp = 90-primOpTag IntToFloatOp = 91-primOpTag IntToDoubleOp = 92-primOpTag WordToFloatOp = 93-primOpTag WordToDoubleOp = 94-primOpTag ISllOp = 95-primOpTag ISraOp = 96-primOpTag ISrlOp = 97-primOpTag WordAddOp = 98-primOpTag WordAddCOp = 99-primOpTag WordSubCOp = 100-primOpTag WordAdd2Op = 101-primOpTag WordSubOp = 102-primOpTag WordMulOp = 103-primOpTag WordMul2Op = 104-primOpTag WordQuotOp = 105-primOpTag WordRemOp = 106-primOpTag WordQuotRemOp = 107-primOpTag WordQuotRem2Op = 108-primOpTag AndOp = 109-primOpTag OrOp = 110-primOpTag XorOp = 111-primOpTag NotOp = 112-primOpTag SllOp = 113-primOpTag SrlOp = 114-primOpTag WordToIntOp = 115-primOpTag WordGtOp = 116-primOpTag WordGeOp = 117-primOpTag WordEqOp = 118-primOpTag WordNeOp = 119-primOpTag WordLtOp = 120-primOpTag WordLeOp = 121-primOpTag PopCnt8Op = 122-primOpTag PopCnt16Op = 123-primOpTag PopCnt32Op = 124-primOpTag PopCnt64Op = 125-primOpTag PopCntOp = 126-primOpTag Pdep8Op = 127-primOpTag Pdep16Op = 128-primOpTag Pdep32Op = 129-primOpTag Pdep64Op = 130-primOpTag PdepOp = 131-primOpTag Pext8Op = 132-primOpTag Pext16Op = 133-primOpTag Pext32Op = 134-primOpTag Pext64Op = 135-primOpTag PextOp = 136-primOpTag Clz8Op = 137-primOpTag Clz16Op = 138-primOpTag Clz32Op = 139-primOpTag Clz64Op = 140-primOpTag ClzOp = 141-primOpTag Ctz8Op = 142-primOpTag Ctz16Op = 143-primOpTag Ctz32Op = 144-primOpTag Ctz64Op = 145-primOpTag CtzOp = 146-primOpTag BSwap16Op = 147-primOpTag BSwap32Op = 148-primOpTag BSwap64Op = 149-primOpTag BSwapOp = 150-primOpTag BRev8Op = 151-primOpTag BRev16Op = 152-primOpTag BRev32Op = 153-primOpTag BRev64Op = 154-primOpTag BRevOp = 155-primOpTag Narrow8IntOp = 156-primOpTag Narrow16IntOp = 157-primOpTag Narrow32IntOp = 158-primOpTag Narrow8WordOp = 159-primOpTag Narrow16WordOp = 160-primOpTag Narrow32WordOp = 161-primOpTag DoubleGtOp = 162-primOpTag DoubleGeOp = 163-primOpTag DoubleEqOp = 164-primOpTag DoubleNeOp = 165-primOpTag DoubleLtOp = 166-primOpTag DoubleLeOp = 167-primOpTag DoubleAddOp = 168-primOpTag DoubleSubOp = 169-primOpTag DoubleMulOp = 170-primOpTag DoubleDivOp = 171-primOpTag DoubleNegOp = 172-primOpTag DoubleFabsOp = 173-primOpTag DoubleToIntOp = 174-primOpTag DoubleToFloatOp = 175-primOpTag DoubleExpOp = 176-primOpTag DoubleExpM1Op = 177-primOpTag DoubleLogOp = 178-primOpTag DoubleLog1POp = 179-primOpTag DoubleSqrtOp = 180-primOpTag DoubleSinOp = 181-primOpTag DoubleCosOp = 182-primOpTag DoubleTanOp = 183-primOpTag DoubleAsinOp = 184-primOpTag DoubleAcosOp = 185-primOpTag DoubleAtanOp = 186-primOpTag DoubleSinhOp = 187-primOpTag DoubleCoshOp = 188-primOpTag DoubleTanhOp = 189-primOpTag DoubleAsinhOp = 190-primOpTag DoubleAcoshOp = 191-primOpTag DoubleAtanhOp = 192-primOpTag DoublePowerOp = 193-primOpTag DoubleDecode_2IntOp = 194-primOpTag DoubleDecode_Int64Op = 195-primOpTag FloatGtOp = 196-primOpTag FloatGeOp = 197-primOpTag FloatEqOp = 198-primOpTag FloatNeOp = 199-primOpTag FloatLtOp = 200-primOpTag FloatLeOp = 201-primOpTag FloatAddOp = 202-primOpTag FloatSubOp = 203-primOpTag FloatMulOp = 204-primOpTag FloatDivOp = 205-primOpTag FloatNegOp = 206-primOpTag FloatFabsOp = 207-primOpTag FloatToIntOp = 208-primOpTag FloatExpOp = 209-primOpTag FloatExpM1Op = 210-primOpTag FloatLogOp = 211-primOpTag FloatLog1POp = 212-primOpTag FloatSqrtOp = 213-primOpTag FloatSinOp = 214-primOpTag FloatCosOp = 215-primOpTag FloatTanOp = 216-primOpTag FloatAsinOp = 217-primOpTag FloatAcosOp = 218-primOpTag FloatAtanOp = 219-primOpTag FloatSinhOp = 220-primOpTag FloatCoshOp = 221-primOpTag FloatTanhOp = 222-primOpTag FloatAsinhOp = 223-primOpTag FloatAcoshOp = 224-primOpTag FloatAtanhOp = 225-primOpTag FloatPowerOp = 226-primOpTag FloatToDoubleOp = 227-primOpTag FloatDecode_IntOp = 228-primOpTag NewArrayOp = 229-primOpTag SameMutableArrayOp = 230-primOpTag ReadArrayOp = 231-primOpTag WriteArrayOp = 232-primOpTag SizeofArrayOp = 233-primOpTag SizeofMutableArrayOp = 234-primOpTag IndexArrayOp = 235-primOpTag UnsafeFreezeArrayOp = 236-primOpTag UnsafeThawArrayOp = 237-primOpTag CopyArrayOp = 238-primOpTag CopyMutableArrayOp = 239-primOpTag CloneArrayOp = 240-primOpTag CloneMutableArrayOp = 241-primOpTag FreezeArrayOp = 242-primOpTag ThawArrayOp = 243-primOpTag CasArrayOp = 244-primOpTag NewSmallArrayOp = 245-primOpTag SameSmallMutableArrayOp = 246-primOpTag ShrinkSmallMutableArrayOp_Char = 247-primOpTag ReadSmallArrayOp = 248-primOpTag WriteSmallArrayOp = 249-primOpTag SizeofSmallArrayOp = 250-primOpTag SizeofSmallMutableArrayOp = 251-primOpTag GetSizeofSmallMutableArrayOp = 252-primOpTag IndexSmallArrayOp = 253-primOpTag UnsafeFreezeSmallArrayOp = 254-primOpTag UnsafeThawSmallArrayOp = 255-primOpTag CopySmallArrayOp = 256-primOpTag CopySmallMutableArrayOp = 257-primOpTag CloneSmallArrayOp = 258-primOpTag CloneSmallMutableArrayOp = 259-primOpTag FreezeSmallArrayOp = 260-primOpTag ThawSmallArrayOp = 261-primOpTag CasSmallArrayOp = 262-primOpTag NewByteArrayOp_Char = 263-primOpTag NewPinnedByteArrayOp_Char = 264-primOpTag NewAlignedPinnedByteArrayOp_Char = 265-primOpTag MutableByteArrayIsPinnedOp = 266-primOpTag ByteArrayIsPinnedOp = 267-primOpTag ByteArrayContents_Char = 268-primOpTag SameMutableByteArrayOp = 269-primOpTag ShrinkMutableByteArrayOp_Char = 270-primOpTag ResizeMutableByteArrayOp_Char = 271-primOpTag UnsafeFreezeByteArrayOp = 272-primOpTag SizeofByteArrayOp = 273-primOpTag SizeofMutableByteArrayOp = 274-primOpTag GetSizeofMutableByteArrayOp = 275-primOpTag IndexByteArrayOp_Char = 276-primOpTag IndexByteArrayOp_WideChar = 277-primOpTag IndexByteArrayOp_Int = 278-primOpTag IndexByteArrayOp_Word = 279-primOpTag IndexByteArrayOp_Addr = 280-primOpTag IndexByteArrayOp_Float = 281-primOpTag IndexByteArrayOp_Double = 282-primOpTag IndexByteArrayOp_StablePtr = 283-primOpTag IndexByteArrayOp_Int8 = 284-primOpTag IndexByteArrayOp_Int16 = 285-primOpTag IndexByteArrayOp_Int32 = 286-primOpTag IndexByteArrayOp_Int64 = 287-primOpTag IndexByteArrayOp_Word8 = 288-primOpTag IndexByteArrayOp_Word16 = 289-primOpTag IndexByteArrayOp_Word32 = 290-primOpTag IndexByteArrayOp_Word64 = 291-primOpTag IndexByteArrayOp_Word8AsChar = 292-primOpTag IndexByteArrayOp_Word8AsWideChar = 293-primOpTag IndexByteArrayOp_Word8AsInt = 294-primOpTag IndexByteArrayOp_Word8AsWord = 295-primOpTag IndexByteArrayOp_Word8AsAddr = 296-primOpTag IndexByteArrayOp_Word8AsFloat = 297-primOpTag IndexByteArrayOp_Word8AsDouble = 298-primOpTag IndexByteArrayOp_Word8AsStablePtr = 299-primOpTag IndexByteArrayOp_Word8AsInt16 = 300-primOpTag IndexByteArrayOp_Word8AsInt32 = 301-primOpTag IndexByteArrayOp_Word8AsInt64 = 302-primOpTag IndexByteArrayOp_Word8AsWord16 = 303-primOpTag IndexByteArrayOp_Word8AsWord32 = 304-primOpTag IndexByteArrayOp_Word8AsWord64 = 305-primOpTag ReadByteArrayOp_Char = 306-primOpTag ReadByteArrayOp_WideChar = 307-primOpTag ReadByteArrayOp_Int = 308-primOpTag ReadByteArrayOp_Word = 309-primOpTag ReadByteArrayOp_Addr = 310-primOpTag ReadByteArrayOp_Float = 311-primOpTag ReadByteArrayOp_Double = 312-primOpTag ReadByteArrayOp_StablePtr = 313-primOpTag ReadByteArrayOp_Int8 = 314-primOpTag ReadByteArrayOp_Int16 = 315-primOpTag ReadByteArrayOp_Int32 = 316-primOpTag ReadByteArrayOp_Int64 = 317-primOpTag ReadByteArrayOp_Word8 = 318-primOpTag ReadByteArrayOp_Word16 = 319-primOpTag ReadByteArrayOp_Word32 = 320-primOpTag ReadByteArrayOp_Word64 = 321-primOpTag ReadByteArrayOp_Word8AsChar = 322-primOpTag ReadByteArrayOp_Word8AsWideChar = 323-primOpTag ReadByteArrayOp_Word8AsInt = 324-primOpTag ReadByteArrayOp_Word8AsWord = 325-primOpTag ReadByteArrayOp_Word8AsAddr = 326-primOpTag ReadByteArrayOp_Word8AsFloat = 327-primOpTag ReadByteArrayOp_Word8AsDouble = 328-primOpTag ReadByteArrayOp_Word8AsStablePtr = 329-primOpTag ReadByteArrayOp_Word8AsInt16 = 330-primOpTag ReadByteArrayOp_Word8AsInt32 = 331-primOpTag ReadByteArrayOp_Word8AsInt64 = 332-primOpTag ReadByteArrayOp_Word8AsWord16 = 333-primOpTag ReadByteArrayOp_Word8AsWord32 = 334-primOpTag ReadByteArrayOp_Word8AsWord64 = 335-primOpTag WriteByteArrayOp_Char = 336-primOpTag WriteByteArrayOp_WideChar = 337-primOpTag WriteByteArrayOp_Int = 338-primOpTag WriteByteArrayOp_Word = 339-primOpTag WriteByteArrayOp_Addr = 340-primOpTag WriteByteArrayOp_Float = 341-primOpTag WriteByteArrayOp_Double = 342-primOpTag WriteByteArrayOp_StablePtr = 343-primOpTag WriteByteArrayOp_Int8 = 344-primOpTag WriteByteArrayOp_Int16 = 345-primOpTag WriteByteArrayOp_Int32 = 346-primOpTag WriteByteArrayOp_Int64 = 347-primOpTag WriteByteArrayOp_Word8 = 348-primOpTag WriteByteArrayOp_Word16 = 349-primOpTag WriteByteArrayOp_Word32 = 350-primOpTag WriteByteArrayOp_Word64 = 351-primOpTag WriteByteArrayOp_Word8AsChar = 352-primOpTag WriteByteArrayOp_Word8AsWideChar = 353-primOpTag WriteByteArrayOp_Word8AsInt = 354-primOpTag WriteByteArrayOp_Word8AsWord = 355-primOpTag WriteByteArrayOp_Word8AsAddr = 356-primOpTag WriteByteArrayOp_Word8AsFloat = 357-primOpTag WriteByteArrayOp_Word8AsDouble = 358-primOpTag WriteByteArrayOp_Word8AsStablePtr = 359-primOpTag WriteByteArrayOp_Word8AsInt16 = 360-primOpTag WriteByteArrayOp_Word8AsInt32 = 361-primOpTag WriteByteArrayOp_Word8AsInt64 = 362-primOpTag WriteByteArrayOp_Word8AsWord16 = 363-primOpTag WriteByteArrayOp_Word8AsWord32 = 364-primOpTag WriteByteArrayOp_Word8AsWord64 = 365-primOpTag CompareByteArraysOp = 366-primOpTag CopyByteArrayOp = 367-primOpTag CopyMutableByteArrayOp = 368-primOpTag CopyByteArrayToAddrOp = 369-primOpTag CopyMutableByteArrayToAddrOp = 370-primOpTag CopyAddrToByteArrayOp = 371-primOpTag SetByteArrayOp = 372-primOpTag AtomicReadByteArrayOp_Int = 373-primOpTag AtomicWriteByteArrayOp_Int = 374-primOpTag CasByteArrayOp_Int = 375-primOpTag FetchAddByteArrayOp_Int = 376-primOpTag FetchSubByteArrayOp_Int = 377-primOpTag FetchAndByteArrayOp_Int = 378-primOpTag FetchNandByteArrayOp_Int = 379-primOpTag FetchOrByteArrayOp_Int = 380-primOpTag FetchXorByteArrayOp_Int = 381-primOpTag NewArrayArrayOp = 382-primOpTag SameMutableArrayArrayOp = 383-primOpTag UnsafeFreezeArrayArrayOp = 384-primOpTag SizeofArrayArrayOp = 385-primOpTag SizeofMutableArrayArrayOp = 386-primOpTag IndexArrayArrayOp_ByteArray = 387-primOpTag IndexArrayArrayOp_ArrayArray = 388-primOpTag ReadArrayArrayOp_ByteArray = 389-primOpTag ReadArrayArrayOp_MutableByteArray = 390-primOpTag ReadArrayArrayOp_ArrayArray = 391-primOpTag ReadArrayArrayOp_MutableArrayArray = 392-primOpTag WriteArrayArrayOp_ByteArray = 393-primOpTag WriteArrayArrayOp_MutableByteArray = 394-primOpTag WriteArrayArrayOp_ArrayArray = 395-primOpTag WriteArrayArrayOp_MutableArrayArray = 396-primOpTag CopyArrayArrayOp = 397-primOpTag CopyMutableArrayArrayOp = 398-primOpTag AddrAddOp = 399-primOpTag AddrSubOp = 400-primOpTag AddrRemOp = 401-primOpTag AddrToIntOp = 402-primOpTag IntToAddrOp = 403-primOpTag AddrGtOp = 404-primOpTag AddrGeOp = 405-primOpTag AddrEqOp = 406-primOpTag AddrNeOp = 407-primOpTag AddrLtOp = 408-primOpTag AddrLeOp = 409-primOpTag IndexOffAddrOp_Char = 410-primOpTag IndexOffAddrOp_WideChar = 411-primOpTag IndexOffAddrOp_Int = 412-primOpTag IndexOffAddrOp_Word = 413-primOpTag IndexOffAddrOp_Addr = 414-primOpTag IndexOffAddrOp_Float = 415-primOpTag IndexOffAddrOp_Double = 416-primOpTag IndexOffAddrOp_StablePtr = 417-primOpTag IndexOffAddrOp_Int8 = 418-primOpTag IndexOffAddrOp_Int16 = 419-primOpTag IndexOffAddrOp_Int32 = 420-primOpTag IndexOffAddrOp_Int64 = 421-primOpTag IndexOffAddrOp_Word8 = 422-primOpTag IndexOffAddrOp_Word16 = 423-primOpTag IndexOffAddrOp_Word32 = 424-primOpTag IndexOffAddrOp_Word64 = 425-primOpTag ReadOffAddrOp_Char = 426-primOpTag ReadOffAddrOp_WideChar = 427-primOpTag ReadOffAddrOp_Int = 428-primOpTag ReadOffAddrOp_Word = 429-primOpTag ReadOffAddrOp_Addr = 430-primOpTag ReadOffAddrOp_Float = 431-primOpTag ReadOffAddrOp_Double = 432-primOpTag ReadOffAddrOp_StablePtr = 433-primOpTag ReadOffAddrOp_Int8 = 434-primOpTag ReadOffAddrOp_Int16 = 435-primOpTag ReadOffAddrOp_Int32 = 436-primOpTag ReadOffAddrOp_Int64 = 437-primOpTag ReadOffAddrOp_Word8 = 438-primOpTag ReadOffAddrOp_Word16 = 439-primOpTag ReadOffAddrOp_Word32 = 440-primOpTag ReadOffAddrOp_Word64 = 441-primOpTag WriteOffAddrOp_Char = 442-primOpTag WriteOffAddrOp_WideChar = 443-primOpTag WriteOffAddrOp_Int = 444-primOpTag WriteOffAddrOp_Word = 445-primOpTag WriteOffAddrOp_Addr = 446-primOpTag WriteOffAddrOp_Float = 447-primOpTag WriteOffAddrOp_Double = 448-primOpTag WriteOffAddrOp_StablePtr = 449-primOpTag WriteOffAddrOp_Int8 = 450-primOpTag WriteOffAddrOp_Int16 = 451-primOpTag WriteOffAddrOp_Int32 = 452-primOpTag WriteOffAddrOp_Int64 = 453-primOpTag WriteOffAddrOp_Word8 = 454-primOpTag WriteOffAddrOp_Word16 = 455-primOpTag WriteOffAddrOp_Word32 = 456-primOpTag WriteOffAddrOp_Word64 = 457-primOpTag InterlockedExchange_Addr = 458-primOpTag InterlockedExchange_Int = 459-primOpTag AtomicCompareExchange_Int = 460-primOpTag AtomicCompareExchange_Addr = 461-primOpTag NewMutVarOp = 462-primOpTag ReadMutVarOp = 463-primOpTag WriteMutVarOp = 464-primOpTag SameMutVarOp = 465-primOpTag AtomicModifyMutVar2Op = 466-primOpTag AtomicModifyMutVar_Op = 467-primOpTag CasMutVarOp = 468-primOpTag CatchOp = 469-primOpTag RaiseOp = 470-primOpTag RaiseIOOp = 471-primOpTag MaskAsyncExceptionsOp = 472-primOpTag MaskUninterruptibleOp = 473-primOpTag UnmaskAsyncExceptionsOp = 474-primOpTag MaskStatus = 475-primOpTag AtomicallyOp = 476-primOpTag RetryOp = 477-primOpTag CatchRetryOp = 478-primOpTag CatchSTMOp = 479-primOpTag NewTVarOp = 480-primOpTag ReadTVarOp = 481-primOpTag ReadTVarIOOp = 482-primOpTag WriteTVarOp = 483-primOpTag SameTVarOp = 484-primOpTag NewMVarOp = 485-primOpTag TakeMVarOp = 486-primOpTag TryTakeMVarOp = 487-primOpTag PutMVarOp = 488-primOpTag TryPutMVarOp = 489-primOpTag ReadMVarOp = 490-primOpTag TryReadMVarOp = 491-primOpTag SameMVarOp = 492-primOpTag IsEmptyMVarOp = 493-primOpTag NewIOPortrOp = 494-primOpTag ReadIOPortOp = 495-primOpTag WriteIOPortOp = 496-primOpTag SameIOPortOp = 497-primOpTag DelayOp = 498-primOpTag WaitReadOp = 499-primOpTag WaitWriteOp = 500-primOpTag ForkOp = 501-primOpTag ForkOnOp = 502-primOpTag KillThreadOp = 503-primOpTag YieldOp = 504-primOpTag MyThreadIdOp = 505-primOpTag LabelThreadOp = 506-primOpTag IsCurrentThreadBoundOp = 507-primOpTag NoDuplicateOp = 508-primOpTag ThreadStatusOp = 509-primOpTag MkWeakOp = 510-primOpTag MkWeakNoFinalizerOp = 511-primOpTag AddCFinalizerToWeakOp = 512-primOpTag DeRefWeakOp = 513-primOpTag FinalizeWeakOp = 514-primOpTag TouchOp = 515-primOpTag MakeStablePtrOp = 516-primOpTag DeRefStablePtrOp = 517-primOpTag EqStablePtrOp = 518-primOpTag MakeStableNameOp = 519-primOpTag EqStableNameOp = 520-primOpTag StableNameToIntOp = 521-primOpTag CompactNewOp = 522-primOpTag CompactResizeOp = 523-primOpTag CompactContainsOp = 524-primOpTag CompactContainsAnyOp = 525-primOpTag CompactGetFirstBlockOp = 526-primOpTag CompactGetNextBlockOp = 527-primOpTag CompactAllocateBlockOp = 528-primOpTag CompactFixupPointersOp = 529-primOpTag CompactAdd = 530-primOpTag CompactAddWithSharing = 531-primOpTag CompactSize = 532-primOpTag ReallyUnsafePtrEqualityOp = 533-primOpTag ParOp = 534-primOpTag SparkOp = 535-primOpTag SeqOp = 536-primOpTag GetSparkOp = 537-primOpTag NumSparks = 538-primOpTag DataToTagOp = 539-primOpTag TagToEnumOp = 540-primOpTag AddrToAnyOp = 541-primOpTag AnyToAddrOp = 542-primOpTag MkApUpd0_Op = 543-primOpTag NewBCOOp = 544-primOpTag UnpackClosureOp = 545-primOpTag ClosureSizeOp = 546-primOpTag GetApStackValOp = 547-primOpTag GetCCSOfOp = 548-primOpTag GetCurrentCCSOp = 549-primOpTag ClearCCSOp = 550-primOpTag TraceEventOp = 551-primOpTag TraceEventBinaryOp = 552-primOpTag TraceMarkerOp = 553-primOpTag SetThreadAllocationCounter = 554-primOpTag (VecBroadcastOp IntVec 16 W8) = 555-primOpTag (VecBroadcastOp IntVec 8 W16) = 556-primOpTag (VecBroadcastOp IntVec 4 W32) = 557-primOpTag (VecBroadcastOp IntVec 2 W64) = 558-primOpTag (VecBroadcastOp IntVec 32 W8) = 559-primOpTag (VecBroadcastOp IntVec 16 W16) = 560-primOpTag (VecBroadcastOp IntVec 8 W32) = 561-primOpTag (VecBroadcastOp IntVec 4 W64) = 562-primOpTag (VecBroadcastOp IntVec 64 W8) = 563-primOpTag (VecBroadcastOp IntVec 32 W16) = 564-primOpTag (VecBroadcastOp IntVec 16 W32) = 565-primOpTag (VecBroadcastOp IntVec 8 W64) = 566-primOpTag (VecBroadcastOp WordVec 16 W8) = 567-primOpTag (VecBroadcastOp WordVec 8 W16) = 568-primOpTag (VecBroadcastOp WordVec 4 W32) = 569-primOpTag (VecBroadcastOp WordVec 2 W64) = 570-primOpTag (VecBroadcastOp WordVec 32 W8) = 571-primOpTag (VecBroadcastOp WordVec 16 W16) = 572-primOpTag (VecBroadcastOp WordVec 8 W32) = 573-primOpTag (VecBroadcastOp WordVec 4 W64) = 574-primOpTag (VecBroadcastOp WordVec 64 W8) = 575-primOpTag (VecBroadcastOp WordVec 32 W16) = 576-primOpTag (VecBroadcastOp WordVec 16 W32) = 577-primOpTag (VecBroadcastOp WordVec 8 W64) = 578-primOpTag (VecBroadcastOp FloatVec 4 W32) = 579-primOpTag (VecBroadcastOp FloatVec 2 W64) = 580-primOpTag (VecBroadcastOp FloatVec 8 W32) = 581-primOpTag (VecBroadcastOp FloatVec 4 W64) = 582-primOpTag (VecBroadcastOp FloatVec 16 W32) = 583-primOpTag (VecBroadcastOp FloatVec 8 W64) = 584-primOpTag (VecPackOp IntVec 16 W8) = 585-primOpTag (VecPackOp IntVec 8 W16) = 586-primOpTag (VecPackOp IntVec 4 W32) = 587-primOpTag (VecPackOp IntVec 2 W64) = 588-primOpTag (VecPackOp IntVec 32 W8) = 589-primOpTag (VecPackOp IntVec 16 W16) = 590-primOpTag (VecPackOp IntVec 8 W32) = 591-primOpTag (VecPackOp IntVec 4 W64) = 592-primOpTag (VecPackOp IntVec 64 W8) = 593-primOpTag (VecPackOp IntVec 32 W16) = 594-primOpTag (VecPackOp IntVec 16 W32) = 595-primOpTag (VecPackOp IntVec 8 W64) = 596-primOpTag (VecPackOp WordVec 16 W8) = 597-primOpTag (VecPackOp WordVec 8 W16) = 598-primOpTag (VecPackOp WordVec 4 W32) = 599-primOpTag (VecPackOp WordVec 2 W64) = 600-primOpTag (VecPackOp WordVec 32 W8) = 601-primOpTag (VecPackOp WordVec 16 W16) = 602-primOpTag (VecPackOp WordVec 8 W32) = 603-primOpTag (VecPackOp WordVec 4 W64) = 604-primOpTag (VecPackOp WordVec 64 W8) = 605-primOpTag (VecPackOp WordVec 32 W16) = 606-primOpTag (VecPackOp WordVec 16 W32) = 607-primOpTag (VecPackOp WordVec 8 W64) = 608-primOpTag (VecPackOp FloatVec 4 W32) = 609-primOpTag (VecPackOp FloatVec 2 W64) = 610-primOpTag (VecPackOp FloatVec 8 W32) = 611-primOpTag (VecPackOp FloatVec 4 W64) = 612-primOpTag (VecPackOp FloatVec 16 W32) = 613-primOpTag (VecPackOp FloatVec 8 W64) = 614-primOpTag (VecUnpackOp IntVec 16 W8) = 615-primOpTag (VecUnpackOp IntVec 8 W16) = 616-primOpTag (VecUnpackOp IntVec 4 W32) = 617-primOpTag (VecUnpackOp IntVec 2 W64) = 618-primOpTag (VecUnpackOp IntVec 32 W8) = 619-primOpTag (VecUnpackOp IntVec 16 W16) = 620-primOpTag (VecUnpackOp IntVec 8 W32) = 621-primOpTag (VecUnpackOp IntVec 4 W64) = 622-primOpTag (VecUnpackOp IntVec 64 W8) = 623-primOpTag (VecUnpackOp IntVec 32 W16) = 624-primOpTag (VecUnpackOp IntVec 16 W32) = 625-primOpTag (VecUnpackOp IntVec 8 W64) = 626-primOpTag (VecUnpackOp WordVec 16 W8) = 627-primOpTag (VecUnpackOp WordVec 8 W16) = 628-primOpTag (VecUnpackOp WordVec 4 W32) = 629-primOpTag (VecUnpackOp WordVec 2 W64) = 630-primOpTag (VecUnpackOp WordVec 32 W8) = 631-primOpTag (VecUnpackOp WordVec 16 W16) = 632-primOpTag (VecUnpackOp WordVec 8 W32) = 633-primOpTag (VecUnpackOp WordVec 4 W64) = 634-primOpTag (VecUnpackOp WordVec 64 W8) = 635-primOpTag (VecUnpackOp WordVec 32 W16) = 636-primOpTag (VecUnpackOp WordVec 16 W32) = 637-primOpTag (VecUnpackOp WordVec 8 W64) = 638-primOpTag (VecUnpackOp FloatVec 4 W32) = 639-primOpTag (VecUnpackOp FloatVec 2 W64) = 640-primOpTag (VecUnpackOp FloatVec 8 W32) = 641-primOpTag (VecUnpackOp FloatVec 4 W64) = 642-primOpTag (VecUnpackOp FloatVec 16 W32) = 643-primOpTag (VecUnpackOp FloatVec 8 W64) = 644-primOpTag (VecInsertOp IntVec 16 W8) = 645-primOpTag (VecInsertOp IntVec 8 W16) = 646-primOpTag (VecInsertOp IntVec 4 W32) = 647-primOpTag (VecInsertOp IntVec 2 W64) = 648-primOpTag (VecInsertOp IntVec 32 W8) = 649-primOpTag (VecInsertOp IntVec 16 W16) = 650-primOpTag (VecInsertOp IntVec 8 W32) = 651-primOpTag (VecInsertOp IntVec 4 W64) = 652-primOpTag (VecInsertOp IntVec 64 W8) = 653-primOpTag (VecInsertOp IntVec 32 W16) = 654-primOpTag (VecInsertOp IntVec 16 W32) = 655-primOpTag (VecInsertOp IntVec 8 W64) = 656-primOpTag (VecInsertOp WordVec 16 W8) = 657-primOpTag (VecInsertOp WordVec 8 W16) = 658-primOpTag (VecInsertOp WordVec 4 W32) = 659-primOpTag (VecInsertOp WordVec 2 W64) = 660-primOpTag (VecInsertOp WordVec 32 W8) = 661-primOpTag (VecInsertOp WordVec 16 W16) = 662-primOpTag (VecInsertOp WordVec 8 W32) = 663-primOpTag (VecInsertOp WordVec 4 W64) = 664-primOpTag (VecInsertOp WordVec 64 W8) = 665-primOpTag (VecInsertOp WordVec 32 W16) = 666-primOpTag (VecInsertOp WordVec 16 W32) = 667-primOpTag (VecInsertOp WordVec 8 W64) = 668-primOpTag (VecInsertOp FloatVec 4 W32) = 669-primOpTag (VecInsertOp FloatVec 2 W64) = 670-primOpTag (VecInsertOp FloatVec 8 W32) = 671-primOpTag (VecInsertOp FloatVec 4 W64) = 672-primOpTag (VecInsertOp FloatVec 16 W32) = 673-primOpTag (VecInsertOp FloatVec 8 W64) = 674-primOpTag (VecAddOp IntVec 16 W8) = 675-primOpTag (VecAddOp IntVec 8 W16) = 676-primOpTag (VecAddOp IntVec 4 W32) = 677-primOpTag (VecAddOp IntVec 2 W64) = 678-primOpTag (VecAddOp IntVec 32 W8) = 679-primOpTag (VecAddOp IntVec 16 W16) = 680-primOpTag (VecAddOp IntVec 8 W32) = 681-primOpTag (VecAddOp IntVec 4 W64) = 682-primOpTag (VecAddOp IntVec 64 W8) = 683-primOpTag (VecAddOp IntVec 32 W16) = 684-primOpTag (VecAddOp IntVec 16 W32) = 685-primOpTag (VecAddOp IntVec 8 W64) = 686-primOpTag (VecAddOp WordVec 16 W8) = 687-primOpTag (VecAddOp WordVec 8 W16) = 688-primOpTag (VecAddOp WordVec 4 W32) = 689-primOpTag (VecAddOp WordVec 2 W64) = 690-primOpTag (VecAddOp WordVec 32 W8) = 691-primOpTag (VecAddOp WordVec 16 W16) = 692-primOpTag (VecAddOp WordVec 8 W32) = 693-primOpTag (VecAddOp WordVec 4 W64) = 694-primOpTag (VecAddOp WordVec 64 W8) = 695-primOpTag (VecAddOp WordVec 32 W16) = 696-primOpTag (VecAddOp WordVec 16 W32) = 697-primOpTag (VecAddOp WordVec 8 W64) = 698-primOpTag (VecAddOp FloatVec 4 W32) = 699-primOpTag (VecAddOp FloatVec 2 W64) = 700-primOpTag (VecAddOp FloatVec 8 W32) = 701-primOpTag (VecAddOp FloatVec 4 W64) = 702-primOpTag (VecAddOp FloatVec 16 W32) = 703-primOpTag (VecAddOp FloatVec 8 W64) = 704-primOpTag (VecSubOp IntVec 16 W8) = 705-primOpTag (VecSubOp IntVec 8 W16) = 706-primOpTag (VecSubOp IntVec 4 W32) = 707-primOpTag (VecSubOp IntVec 2 W64) = 708-primOpTag (VecSubOp IntVec 32 W8) = 709-primOpTag (VecSubOp IntVec 16 W16) = 710-primOpTag (VecSubOp IntVec 8 W32) = 711-primOpTag (VecSubOp IntVec 4 W64) = 712-primOpTag (VecSubOp IntVec 64 W8) = 713-primOpTag (VecSubOp IntVec 32 W16) = 714-primOpTag (VecSubOp IntVec 16 W32) = 715-primOpTag (VecSubOp IntVec 8 W64) = 716-primOpTag (VecSubOp WordVec 16 W8) = 717-primOpTag (VecSubOp WordVec 8 W16) = 718-primOpTag (VecSubOp WordVec 4 W32) = 719-primOpTag (VecSubOp WordVec 2 W64) = 720-primOpTag (VecSubOp WordVec 32 W8) = 721-primOpTag (VecSubOp WordVec 16 W16) = 722-primOpTag (VecSubOp WordVec 8 W32) = 723-primOpTag (VecSubOp WordVec 4 W64) = 724-primOpTag (VecSubOp WordVec 64 W8) = 725-primOpTag (VecSubOp WordVec 32 W16) = 726-primOpTag (VecSubOp WordVec 16 W32) = 727-primOpTag (VecSubOp WordVec 8 W64) = 728-primOpTag (VecSubOp FloatVec 4 W32) = 729-primOpTag (VecSubOp FloatVec 2 W64) = 730-primOpTag (VecSubOp FloatVec 8 W32) = 731-primOpTag (VecSubOp FloatVec 4 W64) = 732-primOpTag (VecSubOp FloatVec 16 W32) = 733-primOpTag (VecSubOp FloatVec 8 W64) = 734-primOpTag (VecMulOp IntVec 16 W8) = 735-primOpTag (VecMulOp IntVec 8 W16) = 736-primOpTag (VecMulOp IntVec 4 W32) = 737-primOpTag (VecMulOp IntVec 2 W64) = 738-primOpTag (VecMulOp IntVec 32 W8) = 739-primOpTag (VecMulOp IntVec 16 W16) = 740-primOpTag (VecMulOp IntVec 8 W32) = 741-primOpTag (VecMulOp IntVec 4 W64) = 742-primOpTag (VecMulOp IntVec 64 W8) = 743-primOpTag (VecMulOp IntVec 32 W16) = 744-primOpTag (VecMulOp IntVec 16 W32) = 745-primOpTag (VecMulOp IntVec 8 W64) = 746-primOpTag (VecMulOp WordVec 16 W8) = 747-primOpTag (VecMulOp WordVec 8 W16) = 748-primOpTag (VecMulOp WordVec 4 W32) = 749-primOpTag (VecMulOp WordVec 2 W64) = 750-primOpTag (VecMulOp WordVec 32 W8) = 751-primOpTag (VecMulOp WordVec 16 W16) = 752-primOpTag (VecMulOp WordVec 8 W32) = 753-primOpTag (VecMulOp WordVec 4 W64) = 754-primOpTag (VecMulOp WordVec 64 W8) = 755-primOpTag (VecMulOp WordVec 32 W16) = 756-primOpTag (VecMulOp WordVec 16 W32) = 757-primOpTag (VecMulOp WordVec 8 W64) = 758-primOpTag (VecMulOp FloatVec 4 W32) = 759-primOpTag (VecMulOp FloatVec 2 W64) = 760-primOpTag (VecMulOp FloatVec 8 W32) = 761-primOpTag (VecMulOp FloatVec 4 W64) = 762-primOpTag (VecMulOp FloatVec 16 W32) = 763-primOpTag (VecMulOp FloatVec 8 W64) = 764-primOpTag (VecDivOp FloatVec 4 W32) = 765-primOpTag (VecDivOp FloatVec 2 W64) = 766-primOpTag (VecDivOp FloatVec 8 W32) = 767-primOpTag (VecDivOp FloatVec 4 W64) = 768-primOpTag (VecDivOp FloatVec 16 W32) = 769-primOpTag (VecDivOp FloatVec 8 W64) = 770-primOpTag (VecQuotOp IntVec 16 W8) = 771-primOpTag (VecQuotOp IntVec 8 W16) = 772-primOpTag (VecQuotOp IntVec 4 W32) = 773-primOpTag (VecQuotOp IntVec 2 W64) = 774-primOpTag (VecQuotOp IntVec 32 W8) = 775-primOpTag (VecQuotOp IntVec 16 W16) = 776-primOpTag (VecQuotOp IntVec 8 W32) = 777-primOpTag (VecQuotOp IntVec 4 W64) = 778-primOpTag (VecQuotOp IntVec 64 W8) = 779-primOpTag (VecQuotOp IntVec 32 W16) = 780-primOpTag (VecQuotOp IntVec 16 W32) = 781-primOpTag (VecQuotOp IntVec 8 W64) = 782-primOpTag (VecQuotOp WordVec 16 W8) = 783-primOpTag (VecQuotOp WordVec 8 W16) = 784-primOpTag (VecQuotOp WordVec 4 W32) = 785-primOpTag (VecQuotOp WordVec 2 W64) = 786-primOpTag (VecQuotOp WordVec 32 W8) = 787-primOpTag (VecQuotOp WordVec 16 W16) = 788-primOpTag (VecQuotOp WordVec 8 W32) = 789-primOpTag (VecQuotOp WordVec 4 W64) = 790-primOpTag (VecQuotOp WordVec 64 W8) = 791-primOpTag (VecQuotOp WordVec 32 W16) = 792-primOpTag (VecQuotOp WordVec 16 W32) = 793-primOpTag (VecQuotOp WordVec 8 W64) = 794-primOpTag (VecRemOp IntVec 16 W8) = 795-primOpTag (VecRemOp IntVec 8 W16) = 796-primOpTag (VecRemOp IntVec 4 W32) = 797-primOpTag (VecRemOp IntVec 2 W64) = 798-primOpTag (VecRemOp IntVec 32 W8) = 799-primOpTag (VecRemOp IntVec 16 W16) = 800-primOpTag (VecRemOp IntVec 8 W32) = 801-primOpTag (VecRemOp IntVec 4 W64) = 802-primOpTag (VecRemOp IntVec 64 W8) = 803-primOpTag (VecRemOp IntVec 32 W16) = 804-primOpTag (VecRemOp IntVec 16 W32) = 805-primOpTag (VecRemOp IntVec 8 W64) = 806-primOpTag (VecRemOp WordVec 16 W8) = 807-primOpTag (VecRemOp WordVec 8 W16) = 808-primOpTag (VecRemOp WordVec 4 W32) = 809-primOpTag (VecRemOp WordVec 2 W64) = 810-primOpTag (VecRemOp WordVec 32 W8) = 811-primOpTag (VecRemOp WordVec 16 W16) = 812-primOpTag (VecRemOp WordVec 8 W32) = 813-primOpTag (VecRemOp WordVec 4 W64) = 814-primOpTag (VecRemOp WordVec 64 W8) = 815-primOpTag (VecRemOp WordVec 32 W16) = 816-primOpTag (VecRemOp WordVec 16 W32) = 817-primOpTag (VecRemOp WordVec 8 W64) = 818-primOpTag (VecNegOp IntVec 16 W8) = 819-primOpTag (VecNegOp IntVec 8 W16) = 820-primOpTag (VecNegOp IntVec 4 W32) = 821-primOpTag (VecNegOp IntVec 2 W64) = 822-primOpTag (VecNegOp IntVec 32 W8) = 823-primOpTag (VecNegOp IntVec 16 W16) = 824-primOpTag (VecNegOp IntVec 8 W32) = 825-primOpTag (VecNegOp IntVec 4 W64) = 826-primOpTag (VecNegOp IntVec 64 W8) = 827-primOpTag (VecNegOp IntVec 32 W16) = 828-primOpTag (VecNegOp IntVec 16 W32) = 829-primOpTag (VecNegOp IntVec 8 W64) = 830-primOpTag (VecNegOp FloatVec 4 W32) = 831-primOpTag (VecNegOp FloatVec 2 W64) = 832-primOpTag (VecNegOp FloatVec 8 W32) = 833-primOpTag (VecNegOp FloatVec 4 W64) = 834-primOpTag (VecNegOp FloatVec 16 W32) = 835-primOpTag (VecNegOp FloatVec 8 W64) = 836-primOpTag (VecIndexByteArrayOp IntVec 16 W8) = 837-primOpTag (VecIndexByteArrayOp IntVec 8 W16) = 838-primOpTag (VecIndexByteArrayOp IntVec 4 W32) = 839-primOpTag (VecIndexByteArrayOp IntVec 2 W64) = 840-primOpTag (VecIndexByteArrayOp IntVec 32 W8) = 841-primOpTag (VecIndexByteArrayOp IntVec 16 W16) = 842-primOpTag (VecIndexByteArrayOp IntVec 8 W32) = 843-primOpTag (VecIndexByteArrayOp IntVec 4 W64) = 844-primOpTag (VecIndexByteArrayOp IntVec 64 W8) = 845-primOpTag (VecIndexByteArrayOp IntVec 32 W16) = 846-primOpTag (VecIndexByteArrayOp IntVec 16 W32) = 847-primOpTag (VecIndexByteArrayOp IntVec 8 W64) = 848-primOpTag (VecIndexByteArrayOp WordVec 16 W8) = 849-primOpTag (VecIndexByteArrayOp WordVec 8 W16) = 850-primOpTag (VecIndexByteArrayOp WordVec 4 W32) = 851-primOpTag (VecIndexByteArrayOp WordVec 2 W64) = 852-primOpTag (VecIndexByteArrayOp WordVec 32 W8) = 853-primOpTag (VecIndexByteArrayOp WordVec 16 W16) = 854-primOpTag (VecIndexByteArrayOp WordVec 8 W32) = 855-primOpTag (VecIndexByteArrayOp WordVec 4 W64) = 856-primOpTag (VecIndexByteArrayOp WordVec 64 W8) = 857-primOpTag (VecIndexByteArrayOp WordVec 32 W16) = 858-primOpTag (VecIndexByteArrayOp WordVec 16 W32) = 859-primOpTag (VecIndexByteArrayOp WordVec 8 W64) = 860-primOpTag (VecIndexByteArrayOp FloatVec 4 W32) = 861-primOpTag (VecIndexByteArrayOp FloatVec 2 W64) = 862-primOpTag (VecIndexByteArrayOp FloatVec 8 W32) = 863-primOpTag (VecIndexByteArrayOp FloatVec 4 W64) = 864-primOpTag (VecIndexByteArrayOp FloatVec 16 W32) = 865-primOpTag (VecIndexByteArrayOp FloatVec 8 W64) = 866-primOpTag (VecReadByteArrayOp IntVec 16 W8) = 867-primOpTag (VecReadByteArrayOp IntVec 8 W16) = 868-primOpTag (VecReadByteArrayOp IntVec 4 W32) = 869-primOpTag (VecReadByteArrayOp IntVec 2 W64) = 870-primOpTag (VecReadByteArrayOp IntVec 32 W8) = 871-primOpTag (VecReadByteArrayOp IntVec 16 W16) = 872-primOpTag (VecReadByteArrayOp IntVec 8 W32) = 873-primOpTag (VecReadByteArrayOp IntVec 4 W64) = 874-primOpTag (VecReadByteArrayOp IntVec 64 W8) = 875-primOpTag (VecReadByteArrayOp IntVec 32 W16) = 876-primOpTag (VecReadByteArrayOp IntVec 16 W32) = 877-primOpTag (VecReadByteArrayOp IntVec 8 W64) = 878-primOpTag (VecReadByteArrayOp WordVec 16 W8) = 879-primOpTag (VecReadByteArrayOp WordVec 8 W16) = 880-primOpTag (VecReadByteArrayOp WordVec 4 W32) = 881-primOpTag (VecReadByteArrayOp WordVec 2 W64) = 882-primOpTag (VecReadByteArrayOp WordVec 32 W8) = 883-primOpTag (VecReadByteArrayOp WordVec 16 W16) = 884-primOpTag (VecReadByteArrayOp WordVec 8 W32) = 885-primOpTag (VecReadByteArrayOp WordVec 4 W64) = 886-primOpTag (VecReadByteArrayOp WordVec 64 W8) = 887-primOpTag (VecReadByteArrayOp WordVec 32 W16) = 888-primOpTag (VecReadByteArrayOp WordVec 16 W32) = 889-primOpTag (VecReadByteArrayOp WordVec 8 W64) = 890-primOpTag (VecReadByteArrayOp FloatVec 4 W32) = 891-primOpTag (VecReadByteArrayOp FloatVec 2 W64) = 892-primOpTag (VecReadByteArrayOp FloatVec 8 W32) = 893-primOpTag (VecReadByteArrayOp FloatVec 4 W64) = 894-primOpTag (VecReadByteArrayOp FloatVec 16 W32) = 895-primOpTag (VecReadByteArrayOp FloatVec 8 W64) = 896-primOpTag (VecWriteByteArrayOp IntVec 16 W8) = 897-primOpTag (VecWriteByteArrayOp IntVec 8 W16) = 898-primOpTag (VecWriteByteArrayOp IntVec 4 W32) = 899-primOpTag (VecWriteByteArrayOp IntVec 2 W64) = 900-primOpTag (VecWriteByteArrayOp IntVec 32 W8) = 901-primOpTag (VecWriteByteArrayOp IntVec 16 W16) = 902-primOpTag (VecWriteByteArrayOp IntVec 8 W32) = 903-primOpTag (VecWriteByteArrayOp IntVec 4 W64) = 904-primOpTag (VecWriteByteArrayOp IntVec 64 W8) = 905-primOpTag (VecWriteByteArrayOp IntVec 32 W16) = 906-primOpTag (VecWriteByteArrayOp IntVec 16 W32) = 907-primOpTag (VecWriteByteArrayOp IntVec 8 W64) = 908-primOpTag (VecWriteByteArrayOp WordVec 16 W8) = 909-primOpTag (VecWriteByteArrayOp WordVec 8 W16) = 910-primOpTag (VecWriteByteArrayOp WordVec 4 W32) = 911-primOpTag (VecWriteByteArrayOp WordVec 2 W64) = 912-primOpTag (VecWriteByteArrayOp WordVec 32 W8) = 913-primOpTag (VecWriteByteArrayOp WordVec 16 W16) = 914-primOpTag (VecWriteByteArrayOp WordVec 8 W32) = 915-primOpTag (VecWriteByteArrayOp WordVec 4 W64) = 916-primOpTag (VecWriteByteArrayOp WordVec 64 W8) = 917-primOpTag (VecWriteByteArrayOp WordVec 32 W16) = 918-primOpTag (VecWriteByteArrayOp WordVec 16 W32) = 919-primOpTag (VecWriteByteArrayOp WordVec 8 W64) = 920-primOpTag (VecWriteByteArrayOp FloatVec 4 W32) = 921-primOpTag (VecWriteByteArrayOp FloatVec 2 W64) = 922-primOpTag (VecWriteByteArrayOp FloatVec 8 W32) = 923-primOpTag (VecWriteByteArrayOp FloatVec 4 W64) = 924-primOpTag (VecWriteByteArrayOp FloatVec 16 W32) = 925-primOpTag (VecWriteByteArrayOp FloatVec 8 W64) = 926-primOpTag (VecIndexOffAddrOp IntVec 16 W8) = 927-primOpTag (VecIndexOffAddrOp IntVec 8 W16) = 928-primOpTag (VecIndexOffAddrOp IntVec 4 W32) = 929-primOpTag (VecIndexOffAddrOp IntVec 2 W64) = 930-primOpTag (VecIndexOffAddrOp IntVec 32 W8) = 931-primOpTag (VecIndexOffAddrOp IntVec 16 W16) = 932-primOpTag (VecIndexOffAddrOp IntVec 8 W32) = 933-primOpTag (VecIndexOffAddrOp IntVec 4 W64) = 934-primOpTag (VecIndexOffAddrOp IntVec 64 W8) = 935-primOpTag (VecIndexOffAddrOp IntVec 32 W16) = 936-primOpTag (VecIndexOffAddrOp IntVec 16 W32) = 937-primOpTag (VecIndexOffAddrOp IntVec 8 W64) = 938-primOpTag (VecIndexOffAddrOp WordVec 16 W8) = 939-primOpTag (VecIndexOffAddrOp WordVec 8 W16) = 940-primOpTag (VecIndexOffAddrOp WordVec 4 W32) = 941-primOpTag (VecIndexOffAddrOp WordVec 2 W64) = 942-primOpTag (VecIndexOffAddrOp WordVec 32 W8) = 943-primOpTag (VecIndexOffAddrOp WordVec 16 W16) = 944-primOpTag (VecIndexOffAddrOp WordVec 8 W32) = 945-primOpTag (VecIndexOffAddrOp WordVec 4 W64) = 946-primOpTag (VecIndexOffAddrOp WordVec 64 W8) = 947-primOpTag (VecIndexOffAddrOp WordVec 32 W16) = 948-primOpTag (VecIndexOffAddrOp WordVec 16 W32) = 949-primOpTag (VecIndexOffAddrOp WordVec 8 W64) = 950-primOpTag (VecIndexOffAddrOp FloatVec 4 W32) = 951-primOpTag (VecIndexOffAddrOp FloatVec 2 W64) = 952-primOpTag (VecIndexOffAddrOp FloatVec 8 W32) = 953-primOpTag (VecIndexOffAddrOp FloatVec 4 W64) = 954-primOpTag (VecIndexOffAddrOp FloatVec 16 W32) = 955-primOpTag (VecIndexOffAddrOp FloatVec 8 W64) = 956-primOpTag (VecReadOffAddrOp IntVec 16 W8) = 957-primOpTag (VecReadOffAddrOp IntVec 8 W16) = 958-primOpTag (VecReadOffAddrOp IntVec 4 W32) = 959-primOpTag (VecReadOffAddrOp IntVec 2 W64) = 960-primOpTag (VecReadOffAddrOp IntVec 32 W8) = 961-primOpTag (VecReadOffAddrOp IntVec 16 W16) = 962-primOpTag (VecReadOffAddrOp IntVec 8 W32) = 963-primOpTag (VecReadOffAddrOp IntVec 4 W64) = 964-primOpTag (VecReadOffAddrOp IntVec 64 W8) = 965-primOpTag (VecReadOffAddrOp IntVec 32 W16) = 966-primOpTag (VecReadOffAddrOp IntVec 16 W32) = 967-primOpTag (VecReadOffAddrOp IntVec 8 W64) = 968-primOpTag (VecReadOffAddrOp WordVec 16 W8) = 969-primOpTag (VecReadOffAddrOp WordVec 8 W16) = 970-primOpTag (VecReadOffAddrOp WordVec 4 W32) = 971-primOpTag (VecReadOffAddrOp WordVec 2 W64) = 972-primOpTag (VecReadOffAddrOp WordVec 32 W8) = 973-primOpTag (VecReadOffAddrOp WordVec 16 W16) = 974-primOpTag (VecReadOffAddrOp WordVec 8 W32) = 975-primOpTag (VecReadOffAddrOp WordVec 4 W64) = 976-primOpTag (VecReadOffAddrOp WordVec 64 W8) = 977-primOpTag (VecReadOffAddrOp WordVec 32 W16) = 978-primOpTag (VecReadOffAddrOp WordVec 16 W32) = 979-primOpTag (VecReadOffAddrOp WordVec 8 W64) = 980-primOpTag (VecReadOffAddrOp FloatVec 4 W32) = 981-primOpTag (VecReadOffAddrOp FloatVec 2 W64) = 982-primOpTag (VecReadOffAddrOp FloatVec 8 W32) = 983-primOpTag (VecReadOffAddrOp FloatVec 4 W64) = 984-primOpTag (VecReadOffAddrOp FloatVec 16 W32) = 985-primOpTag (VecReadOffAddrOp FloatVec 8 W64) = 986-primOpTag (VecWriteOffAddrOp IntVec 16 W8) = 987-primOpTag (VecWriteOffAddrOp IntVec 8 W16) = 988-primOpTag (VecWriteOffAddrOp IntVec 4 W32) = 989-primOpTag (VecWriteOffAddrOp IntVec 2 W64) = 990-primOpTag (VecWriteOffAddrOp IntVec 32 W8) = 991-primOpTag (VecWriteOffAddrOp IntVec 16 W16) = 992-primOpTag (VecWriteOffAddrOp IntVec 8 W32) = 993-primOpTag (VecWriteOffAddrOp IntVec 4 W64) = 994-primOpTag (VecWriteOffAddrOp IntVec 64 W8) = 995-primOpTag (VecWriteOffAddrOp IntVec 32 W16) = 996-primOpTag (VecWriteOffAddrOp IntVec 16 W32) = 997-primOpTag (VecWriteOffAddrOp IntVec 8 W64) = 998-primOpTag (VecWriteOffAddrOp WordVec 16 W8) = 999-primOpTag (VecWriteOffAddrOp WordVec 8 W16) = 1000-primOpTag (VecWriteOffAddrOp WordVec 4 W32) = 1001-primOpTag (VecWriteOffAddrOp WordVec 2 W64) = 1002-primOpTag (VecWriteOffAddrOp WordVec 32 W8) = 1003-primOpTag (VecWriteOffAddrOp WordVec 16 W16) = 1004-primOpTag (VecWriteOffAddrOp WordVec 8 W32) = 1005-primOpTag (VecWriteOffAddrOp WordVec 4 W64) = 1006-primOpTag (VecWriteOffAddrOp WordVec 64 W8) = 1007-primOpTag (VecWriteOffAddrOp WordVec 32 W16) = 1008-primOpTag (VecWriteOffAddrOp WordVec 16 W32) = 1009-primOpTag (VecWriteOffAddrOp WordVec 8 W64) = 1010-primOpTag (VecWriteOffAddrOp FloatVec 4 W32) = 1011-primOpTag (VecWriteOffAddrOp FloatVec 2 W64) = 1012-primOpTag (VecWriteOffAddrOp FloatVec 8 W32) = 1013-primOpTag (VecWriteOffAddrOp FloatVec 4 W64) = 1014-primOpTag (VecWriteOffAddrOp FloatVec 16 W32) = 1015-primOpTag (VecWriteOffAddrOp FloatVec 8 W64) = 1016-primOpTag (VecIndexScalarByteArrayOp IntVec 16 W8) = 1017-primOpTag (VecIndexScalarByteArrayOp IntVec 8 W16) = 1018-primOpTag (VecIndexScalarByteArrayOp IntVec 4 W32) = 1019-primOpTag (VecIndexScalarByteArrayOp IntVec 2 W64) = 1020-primOpTag (VecIndexScalarByteArrayOp IntVec 32 W8) = 1021-primOpTag (VecIndexScalarByteArrayOp IntVec 16 W16) = 1022-primOpTag (VecIndexScalarByteArrayOp IntVec 8 W32) = 1023-primOpTag (VecIndexScalarByteArrayOp IntVec 4 W64) = 1024-primOpTag (VecIndexScalarByteArrayOp IntVec 64 W8) = 1025-primOpTag (VecIndexScalarByteArrayOp IntVec 32 W16) = 1026-primOpTag (VecIndexScalarByteArrayOp IntVec 16 W32) = 1027-primOpTag (VecIndexScalarByteArrayOp IntVec 8 W64) = 1028-primOpTag (VecIndexScalarByteArrayOp WordVec 16 W8) = 1029-primOpTag (VecIndexScalarByteArrayOp WordVec 8 W16) = 1030-primOpTag (VecIndexScalarByteArrayOp WordVec 4 W32) = 1031-primOpTag (VecIndexScalarByteArrayOp WordVec 2 W64) = 1032-primOpTag (VecIndexScalarByteArrayOp WordVec 32 W8) = 1033-primOpTag (VecIndexScalarByteArrayOp WordVec 16 W16) = 1034-primOpTag (VecIndexScalarByteArrayOp WordVec 8 W32) = 1035-primOpTag (VecIndexScalarByteArrayOp WordVec 4 W64) = 1036-primOpTag (VecIndexScalarByteArrayOp WordVec 64 W8) = 1037-primOpTag (VecIndexScalarByteArrayOp WordVec 32 W16) = 1038-primOpTag (VecIndexScalarByteArrayOp WordVec 16 W32) = 1039-primOpTag (VecIndexScalarByteArrayOp WordVec 8 W64) = 1040-primOpTag (VecIndexScalarByteArrayOp FloatVec 4 W32) = 1041-primOpTag (VecIndexScalarByteArrayOp FloatVec 2 W64) = 1042-primOpTag (VecIndexScalarByteArrayOp FloatVec 8 W32) = 1043-primOpTag (VecIndexScalarByteArrayOp FloatVec 4 W64) = 1044-primOpTag (VecIndexScalarByteArrayOp FloatVec 16 W32) = 1045-primOpTag (VecIndexScalarByteArrayOp FloatVec 8 W64) = 1046-primOpTag (VecReadScalarByteArrayOp IntVec 16 W8) = 1047-primOpTag (VecReadScalarByteArrayOp IntVec 8 W16) = 1048-primOpTag (VecReadScalarByteArrayOp IntVec 4 W32) = 1049-primOpTag (VecReadScalarByteArrayOp IntVec 2 W64) = 1050-primOpTag (VecReadScalarByteArrayOp IntVec 32 W8) = 1051-primOpTag (VecReadScalarByteArrayOp IntVec 16 W16) = 1052-primOpTag (VecReadScalarByteArrayOp IntVec 8 W32) = 1053-primOpTag (VecReadScalarByteArrayOp IntVec 4 W64) = 1054-primOpTag (VecReadScalarByteArrayOp IntVec 64 W8) = 1055-primOpTag (VecReadScalarByteArrayOp IntVec 32 W16) = 1056-primOpTag (VecReadScalarByteArrayOp IntVec 16 W32) = 1057-primOpTag (VecReadScalarByteArrayOp IntVec 8 W64) = 1058-primOpTag (VecReadScalarByteArrayOp WordVec 16 W8) = 1059-primOpTag (VecReadScalarByteArrayOp WordVec 8 W16) = 1060-primOpTag (VecReadScalarByteArrayOp WordVec 4 W32) = 1061-primOpTag (VecReadScalarByteArrayOp WordVec 2 W64) = 1062-primOpTag (VecReadScalarByteArrayOp WordVec 32 W8) = 1063-primOpTag (VecReadScalarByteArrayOp WordVec 16 W16) = 1064-primOpTag (VecReadScalarByteArrayOp WordVec 8 W32) = 1065-primOpTag (VecReadScalarByteArrayOp WordVec 4 W64) = 1066-primOpTag (VecReadScalarByteArrayOp WordVec 64 W8) = 1067-primOpTag (VecReadScalarByteArrayOp WordVec 32 W16) = 1068-primOpTag (VecReadScalarByteArrayOp WordVec 16 W32) = 1069-primOpTag (VecReadScalarByteArrayOp WordVec 8 W64) = 1070-primOpTag (VecReadScalarByteArrayOp FloatVec 4 W32) = 1071-primOpTag (VecReadScalarByteArrayOp FloatVec 2 W64) = 1072-primOpTag (VecReadScalarByteArrayOp FloatVec 8 W32) = 1073-primOpTag (VecReadScalarByteArrayOp FloatVec 4 W64) = 1074-primOpTag (VecReadScalarByteArrayOp FloatVec 16 W32) = 1075-primOpTag (VecReadScalarByteArrayOp FloatVec 8 W64) = 1076-primOpTag (VecWriteScalarByteArrayOp IntVec 16 W8) = 1077-primOpTag (VecWriteScalarByteArrayOp IntVec 8 W16) = 1078-primOpTag (VecWriteScalarByteArrayOp IntVec 4 W32) = 1079-primOpTag (VecWriteScalarByteArrayOp IntVec 2 W64) = 1080-primOpTag (VecWriteScalarByteArrayOp IntVec 32 W8) = 1081-primOpTag (VecWriteScalarByteArrayOp IntVec 16 W16) = 1082-primOpTag (VecWriteScalarByteArrayOp IntVec 8 W32) = 1083-primOpTag (VecWriteScalarByteArrayOp IntVec 4 W64) = 1084-primOpTag (VecWriteScalarByteArrayOp IntVec 64 W8) = 1085-primOpTag (VecWriteScalarByteArrayOp IntVec 32 W16) = 1086-primOpTag (VecWriteScalarByteArrayOp IntVec 16 W32) = 1087-primOpTag (VecWriteScalarByteArrayOp IntVec 8 W64) = 1088-primOpTag (VecWriteScalarByteArrayOp WordVec 16 W8) = 1089-primOpTag (VecWriteScalarByteArrayOp WordVec 8 W16) = 1090-primOpTag (VecWriteScalarByteArrayOp WordVec 4 W32) = 1091-primOpTag (VecWriteScalarByteArrayOp WordVec 2 W64) = 1092-primOpTag (VecWriteScalarByteArrayOp WordVec 32 W8) = 1093-primOpTag (VecWriteScalarByteArrayOp WordVec 16 W16) = 1094-primOpTag (VecWriteScalarByteArrayOp WordVec 8 W32) = 1095-primOpTag (VecWriteScalarByteArrayOp WordVec 4 W64) = 1096-primOpTag (VecWriteScalarByteArrayOp WordVec 64 W8) = 1097-primOpTag (VecWriteScalarByteArrayOp WordVec 32 W16) = 1098-primOpTag (VecWriteScalarByteArrayOp WordVec 16 W32) = 1099-primOpTag (VecWriteScalarByteArrayOp WordVec 8 W64) = 1100-primOpTag (VecWriteScalarByteArrayOp FloatVec 4 W32) = 1101-primOpTag (VecWriteScalarByteArrayOp FloatVec 2 W64) = 1102-primOpTag (VecWriteScalarByteArrayOp FloatVec 8 W32) = 1103-primOpTag (VecWriteScalarByteArrayOp FloatVec 4 W64) = 1104-primOpTag (VecWriteScalarByteArrayOp FloatVec 16 W32) = 1105-primOpTag (VecWriteScalarByteArrayOp FloatVec 8 W64) = 1106-primOpTag (VecIndexScalarOffAddrOp IntVec 16 W8) = 1107-primOpTag (VecIndexScalarOffAddrOp IntVec 8 W16) = 1108-primOpTag (VecIndexScalarOffAddrOp IntVec 4 W32) = 1109-primOpTag (VecIndexScalarOffAddrOp IntVec 2 W64) = 1110-primOpTag (VecIndexScalarOffAddrOp IntVec 32 W8) = 1111-primOpTag (VecIndexScalarOffAddrOp IntVec 16 W16) = 1112-primOpTag (VecIndexScalarOffAddrOp IntVec 8 W32) = 1113-primOpTag (VecIndexScalarOffAddrOp IntVec 4 W64) = 1114-primOpTag (VecIndexScalarOffAddrOp IntVec 64 W8) = 1115-primOpTag (VecIndexScalarOffAddrOp IntVec 32 W16) = 1116-primOpTag (VecIndexScalarOffAddrOp IntVec 16 W32) = 1117-primOpTag (VecIndexScalarOffAddrOp IntVec 8 W64) = 1118-primOpTag (VecIndexScalarOffAddrOp WordVec 16 W8) = 1119-primOpTag (VecIndexScalarOffAddrOp WordVec 8 W16) = 1120-primOpTag (VecIndexScalarOffAddrOp WordVec 4 W32) = 1121-primOpTag (VecIndexScalarOffAddrOp WordVec 2 W64) = 1122-primOpTag (VecIndexScalarOffAddrOp WordVec 32 W8) = 1123-primOpTag (VecIndexScalarOffAddrOp WordVec 16 W16) = 1124-primOpTag (VecIndexScalarOffAddrOp WordVec 8 W32) = 1125-primOpTag (VecIndexScalarOffAddrOp WordVec 4 W64) = 1126-primOpTag (VecIndexScalarOffAddrOp WordVec 64 W8) = 1127-primOpTag (VecIndexScalarOffAddrOp WordVec 32 W16) = 1128-primOpTag (VecIndexScalarOffAddrOp WordVec 16 W32) = 1129-primOpTag (VecIndexScalarOffAddrOp WordVec 8 W64) = 1130-primOpTag (VecIndexScalarOffAddrOp FloatVec 4 W32) = 1131-primOpTag (VecIndexScalarOffAddrOp FloatVec 2 W64) = 1132-primOpTag (VecIndexScalarOffAddrOp FloatVec 8 W32) = 1133-primOpTag (VecIndexScalarOffAddrOp FloatVec 4 W64) = 1134-primOpTag (VecIndexScalarOffAddrOp FloatVec 16 W32) = 1135-primOpTag (VecIndexScalarOffAddrOp FloatVec 8 W64) = 1136-primOpTag (VecReadScalarOffAddrOp IntVec 16 W8) = 1137-primOpTag (VecReadScalarOffAddrOp IntVec 8 W16) = 1138-primOpTag (VecReadScalarOffAddrOp IntVec 4 W32) = 1139-primOpTag (VecReadScalarOffAddrOp IntVec 2 W64) = 1140-primOpTag (VecReadScalarOffAddrOp IntVec 32 W8) = 1141-primOpTag (VecReadScalarOffAddrOp IntVec 16 W16) = 1142-primOpTag (VecReadScalarOffAddrOp IntVec 8 W32) = 1143-primOpTag (VecReadScalarOffAddrOp IntVec 4 W64) = 1144-primOpTag (VecReadScalarOffAddrOp IntVec 64 W8) = 1145-primOpTag (VecReadScalarOffAddrOp IntVec 32 W16) = 1146-primOpTag (VecReadScalarOffAddrOp IntVec 16 W32) = 1147-primOpTag (VecReadScalarOffAddrOp IntVec 8 W64) = 1148-primOpTag (VecReadScalarOffAddrOp WordVec 16 W8) = 1149-primOpTag (VecReadScalarOffAddrOp WordVec 8 W16) = 1150-primOpTag (VecReadScalarOffAddrOp WordVec 4 W32) = 1151-primOpTag (VecReadScalarOffAddrOp WordVec 2 W64) = 1152-primOpTag (VecReadScalarOffAddrOp WordVec 32 W8) = 1153-primOpTag (VecReadScalarOffAddrOp WordVec 16 W16) = 1154-primOpTag (VecReadScalarOffAddrOp WordVec 8 W32) = 1155-primOpTag (VecReadScalarOffAddrOp WordVec 4 W64) = 1156-primOpTag (VecReadScalarOffAddrOp WordVec 64 W8) = 1157-primOpTag (VecReadScalarOffAddrOp WordVec 32 W16) = 1158-primOpTag (VecReadScalarOffAddrOp WordVec 16 W32) = 1159-primOpTag (VecReadScalarOffAddrOp WordVec 8 W64) = 1160-primOpTag (VecReadScalarOffAddrOp FloatVec 4 W32) = 1161-primOpTag (VecReadScalarOffAddrOp FloatVec 2 W64) = 1162-primOpTag (VecReadScalarOffAddrOp FloatVec 8 W32) = 1163-primOpTag (VecReadScalarOffAddrOp FloatVec 4 W64) = 1164-primOpTag (VecReadScalarOffAddrOp FloatVec 16 W32) = 1165-primOpTag (VecReadScalarOffAddrOp FloatVec 8 W64) = 1166-primOpTag (VecWriteScalarOffAddrOp IntVec 16 W8) = 1167-primOpTag (VecWriteScalarOffAddrOp IntVec 8 W16) = 1168-primOpTag (VecWriteScalarOffAddrOp IntVec 4 W32) = 1169-primOpTag (VecWriteScalarOffAddrOp IntVec 2 W64) = 1170-primOpTag (VecWriteScalarOffAddrOp IntVec 32 W8) = 1171-primOpTag (VecWriteScalarOffAddrOp IntVec 16 W16) = 1172-primOpTag (VecWriteScalarOffAddrOp IntVec 8 W32) = 1173-primOpTag (VecWriteScalarOffAddrOp IntVec 4 W64) = 1174-primOpTag (VecWriteScalarOffAddrOp IntVec 64 W8) = 1175-primOpTag (VecWriteScalarOffAddrOp IntVec 32 W16) = 1176-primOpTag (VecWriteScalarOffAddrOp IntVec 16 W32) = 1177-primOpTag (VecWriteScalarOffAddrOp IntVec 8 W64) = 1178-primOpTag (VecWriteScalarOffAddrOp WordVec 16 W8) = 1179-primOpTag (VecWriteScalarOffAddrOp WordVec 8 W16) = 1180-primOpTag (VecWriteScalarOffAddrOp WordVec 4 W32) = 1181-primOpTag (VecWriteScalarOffAddrOp WordVec 2 W64) = 1182-primOpTag (VecWriteScalarOffAddrOp WordVec 32 W8) = 1183-primOpTag (VecWriteScalarOffAddrOp WordVec 16 W16) = 1184-primOpTag (VecWriteScalarOffAddrOp WordVec 8 W32) = 1185-primOpTag (VecWriteScalarOffAddrOp WordVec 4 W64) = 1186-primOpTag (VecWriteScalarOffAddrOp WordVec 64 W8) = 1187-primOpTag (VecWriteScalarOffAddrOp WordVec 32 W16) = 1188-primOpTag (VecWriteScalarOffAddrOp WordVec 16 W32) = 1189-primOpTag (VecWriteScalarOffAddrOp WordVec 8 W64) = 1190-primOpTag (VecWriteScalarOffAddrOp FloatVec 4 W32) = 1191-primOpTag (VecWriteScalarOffAddrOp FloatVec 2 W64) = 1192-primOpTag (VecWriteScalarOffAddrOp FloatVec 8 W32) = 1193-primOpTag (VecWriteScalarOffAddrOp FloatVec 4 W64) = 1194-primOpTag (VecWriteScalarOffAddrOp FloatVec 16 W32) = 1195-primOpTag (VecWriteScalarOffAddrOp FloatVec 8 W64) = 1196-primOpTag PrefetchByteArrayOp3 = 1197-primOpTag PrefetchMutableByteArrayOp3 = 1198-primOpTag PrefetchAddrOp3 = 1199-primOpTag PrefetchValueOp3 = 1200-primOpTag PrefetchByteArrayOp2 = 1201-primOpTag PrefetchMutableByteArrayOp2 = 1202-primOpTag PrefetchAddrOp2 = 1203-primOpTag PrefetchValueOp2 = 1204-primOpTag PrefetchByteArrayOp1 = 1205-primOpTag PrefetchMutableByteArrayOp1 = 1206-primOpTag PrefetchAddrOp1 = 1207-primOpTag PrefetchValueOp1 = 1208-primOpTag PrefetchByteArrayOp0 = 1209-primOpTag PrefetchMutableByteArrayOp0 = 1210-primOpTag PrefetchAddrOp0 = 1211-primOpTag PrefetchValueOp0 = 1212+maxPrimOpTag = 1224+primOpTag :: PrimOp -> Int+primOpTag CharGtOp = 1+primOpTag CharGeOp = 2+primOpTag CharEqOp = 3+primOpTag CharNeOp = 4+primOpTag CharLtOp = 5+primOpTag CharLeOp = 6+primOpTag OrdOp = 7+primOpTag Int8ExtendOp = 8+primOpTag Int8NarrowOp = 9+primOpTag Int8NegOp = 10+primOpTag Int8AddOp = 11+primOpTag Int8SubOp = 12+primOpTag Int8MulOp = 13+primOpTag Int8QuotOp = 14+primOpTag Int8RemOp = 15+primOpTag Int8QuotRemOp = 16+primOpTag Int8EqOp = 17+primOpTag Int8GeOp = 18+primOpTag Int8GtOp = 19+primOpTag Int8LeOp = 20+primOpTag Int8LtOp = 21+primOpTag Int8NeOp = 22+primOpTag Word8ExtendOp = 23+primOpTag Word8NarrowOp = 24+primOpTag Word8NotOp = 25+primOpTag Word8AddOp = 26+primOpTag Word8SubOp = 27+primOpTag Word8MulOp = 28+primOpTag Word8QuotOp = 29+primOpTag Word8RemOp = 30+primOpTag Word8QuotRemOp = 31+primOpTag Word8EqOp = 32+primOpTag Word8GeOp = 33+primOpTag Word8GtOp = 34+primOpTag Word8LeOp = 35+primOpTag Word8LtOp = 36+primOpTag Word8NeOp = 37+primOpTag Int16ExtendOp = 38+primOpTag Int16NarrowOp = 39+primOpTag Int16NegOp = 40+primOpTag Int16AddOp = 41+primOpTag Int16SubOp = 42+primOpTag Int16MulOp = 43+primOpTag Int16QuotOp = 44+primOpTag Int16RemOp = 45+primOpTag Int16QuotRemOp = 46+primOpTag Int16EqOp = 47+primOpTag Int16GeOp = 48+primOpTag Int16GtOp = 49+primOpTag Int16LeOp = 50+primOpTag Int16LtOp = 51+primOpTag Int16NeOp = 52+primOpTag Word16ExtendOp = 53+primOpTag Word16NarrowOp = 54+primOpTag Word16NotOp = 55+primOpTag Word16AddOp = 56+primOpTag Word16SubOp = 57+primOpTag Word16MulOp = 58+primOpTag Word16QuotOp = 59+primOpTag Word16RemOp = 60+primOpTag Word16QuotRemOp = 61+primOpTag Word16EqOp = 62+primOpTag Word16GeOp = 63+primOpTag Word16GtOp = 64+primOpTag Word16LeOp = 65+primOpTag Word16LtOp = 66+primOpTag Word16NeOp = 67+primOpTag Int32ExtendOp = 68+primOpTag Int32NarrowOp = 69+primOpTag Word32ExtendOp = 70+primOpTag Word32NarrowOp = 71+primOpTag IntAddOp = 72+primOpTag IntSubOp = 73+primOpTag IntMulOp = 74+primOpTag IntMul2Op = 75+primOpTag IntMulMayOfloOp = 76+primOpTag IntQuotOp = 77+primOpTag IntRemOp = 78+primOpTag IntQuotRemOp = 79+primOpTag IntAndOp = 80+primOpTag IntOrOp = 81+primOpTag IntXorOp = 82+primOpTag IntNotOp = 83+primOpTag IntNegOp = 84+primOpTag IntAddCOp = 85+primOpTag IntSubCOp = 86+primOpTag IntGtOp = 87+primOpTag IntGeOp = 88+primOpTag IntEqOp = 89+primOpTag IntNeOp = 90+primOpTag IntLtOp = 91+primOpTag IntLeOp = 92+primOpTag ChrOp = 93+primOpTag IntToWordOp = 94+primOpTag IntToFloatOp = 95+primOpTag IntToDoubleOp = 96+primOpTag WordToFloatOp = 97+primOpTag WordToDoubleOp = 98+primOpTag IntSllOp = 99+primOpTag IntSraOp = 100+primOpTag IntSrlOp = 101+primOpTag WordAddOp = 102+primOpTag WordAddCOp = 103+primOpTag WordSubCOp = 104+primOpTag WordAdd2Op = 105+primOpTag WordSubOp = 106+primOpTag WordMulOp = 107+primOpTag WordMul2Op = 108+primOpTag WordQuotOp = 109+primOpTag WordRemOp = 110+primOpTag WordQuotRemOp = 111+primOpTag WordQuotRem2Op = 112+primOpTag WordAndOp = 113+primOpTag WordOrOp = 114+primOpTag WordXorOp = 115+primOpTag WordNotOp = 116+primOpTag WordSllOp = 117+primOpTag WordSrlOp = 118+primOpTag WordToIntOp = 119+primOpTag WordGtOp = 120+primOpTag WordGeOp = 121+primOpTag WordEqOp = 122+primOpTag WordNeOp = 123+primOpTag WordLtOp = 124+primOpTag WordLeOp = 125+primOpTag PopCnt8Op = 126+primOpTag PopCnt16Op = 127+primOpTag PopCnt32Op = 128+primOpTag PopCnt64Op = 129+primOpTag PopCntOp = 130+primOpTag Pdep8Op = 131+primOpTag Pdep16Op = 132+primOpTag Pdep32Op = 133+primOpTag Pdep64Op = 134+primOpTag PdepOp = 135+primOpTag Pext8Op = 136+primOpTag Pext16Op = 137+primOpTag Pext32Op = 138+primOpTag Pext64Op = 139+primOpTag PextOp = 140+primOpTag Clz8Op = 141+primOpTag Clz16Op = 142+primOpTag Clz32Op = 143+primOpTag Clz64Op = 144+primOpTag ClzOp = 145+primOpTag Ctz8Op = 146+primOpTag Ctz16Op = 147+primOpTag Ctz32Op = 148+primOpTag Ctz64Op = 149+primOpTag CtzOp = 150+primOpTag BSwap16Op = 151+primOpTag BSwap32Op = 152+primOpTag BSwap64Op = 153+primOpTag BSwapOp = 154+primOpTag BRev8Op = 155+primOpTag BRev16Op = 156+primOpTag BRev32Op = 157+primOpTag BRev64Op = 158+primOpTag BRevOp = 159+primOpTag Narrow8IntOp = 160+primOpTag Narrow16IntOp = 161+primOpTag Narrow32IntOp = 162+primOpTag Narrow8WordOp = 163+primOpTag Narrow16WordOp = 164+primOpTag Narrow32WordOp = 165+primOpTag DoubleGtOp = 166+primOpTag DoubleGeOp = 167+primOpTag DoubleEqOp = 168+primOpTag DoubleNeOp = 169+primOpTag DoubleLtOp = 170+primOpTag DoubleLeOp = 171+primOpTag DoubleAddOp = 172+primOpTag DoubleSubOp = 173+primOpTag DoubleMulOp = 174+primOpTag DoubleDivOp = 175+primOpTag DoubleNegOp = 176+primOpTag DoubleFabsOp = 177+primOpTag DoubleToIntOp = 178+primOpTag DoubleToFloatOp = 179+primOpTag DoubleExpOp = 180+primOpTag DoubleExpM1Op = 181+primOpTag DoubleLogOp = 182+primOpTag DoubleLog1POp = 183+primOpTag DoubleSqrtOp = 184+primOpTag DoubleSinOp = 185+primOpTag DoubleCosOp = 186+primOpTag DoubleTanOp = 187+primOpTag DoubleAsinOp = 188+primOpTag DoubleAcosOp = 189+primOpTag DoubleAtanOp = 190+primOpTag DoubleSinhOp = 191+primOpTag DoubleCoshOp = 192+primOpTag DoubleTanhOp = 193+primOpTag DoubleAsinhOp = 194+primOpTag DoubleAcoshOp = 195+primOpTag DoubleAtanhOp = 196+primOpTag DoublePowerOp = 197+primOpTag DoubleDecode_2IntOp = 198+primOpTag DoubleDecode_Int64Op = 199+primOpTag FloatGtOp = 200+primOpTag FloatGeOp = 201+primOpTag FloatEqOp = 202+primOpTag FloatNeOp = 203+primOpTag FloatLtOp = 204+primOpTag FloatLeOp = 205+primOpTag FloatAddOp = 206+primOpTag FloatSubOp = 207+primOpTag FloatMulOp = 208+primOpTag FloatDivOp = 209+primOpTag FloatNegOp = 210+primOpTag FloatFabsOp = 211+primOpTag FloatToIntOp = 212+primOpTag FloatExpOp = 213+primOpTag FloatExpM1Op = 214+primOpTag FloatLogOp = 215+primOpTag FloatLog1POp = 216+primOpTag FloatSqrtOp = 217+primOpTag FloatSinOp = 218+primOpTag FloatCosOp = 219+primOpTag FloatTanOp = 220+primOpTag FloatAsinOp = 221+primOpTag FloatAcosOp = 222+primOpTag FloatAtanOp = 223+primOpTag FloatSinhOp = 224+primOpTag FloatCoshOp = 225+primOpTag FloatTanhOp = 226+primOpTag FloatAsinhOp = 227+primOpTag FloatAcoshOp = 228+primOpTag FloatAtanhOp = 229+primOpTag FloatPowerOp = 230+primOpTag FloatToDoubleOp = 231+primOpTag FloatDecode_IntOp = 232+primOpTag NewArrayOp = 233+primOpTag SameMutableArrayOp = 234+primOpTag ReadArrayOp = 235+primOpTag WriteArrayOp = 236+primOpTag SizeofArrayOp = 237+primOpTag SizeofMutableArrayOp = 238+primOpTag IndexArrayOp = 239+primOpTag UnsafeFreezeArrayOp = 240+primOpTag UnsafeThawArrayOp = 241+primOpTag CopyArrayOp = 242+primOpTag CopyMutableArrayOp = 243+primOpTag CloneArrayOp = 244+primOpTag CloneMutableArrayOp = 245+primOpTag FreezeArrayOp = 246+primOpTag ThawArrayOp = 247+primOpTag CasArrayOp = 248+primOpTag NewSmallArrayOp = 249+primOpTag SameSmallMutableArrayOp = 250+primOpTag ShrinkSmallMutableArrayOp_Char = 251+primOpTag ReadSmallArrayOp = 252+primOpTag WriteSmallArrayOp = 253+primOpTag SizeofSmallArrayOp = 254+primOpTag SizeofSmallMutableArrayOp = 255+primOpTag GetSizeofSmallMutableArrayOp = 256+primOpTag IndexSmallArrayOp = 257+primOpTag UnsafeFreezeSmallArrayOp = 258+primOpTag UnsafeThawSmallArrayOp = 259+primOpTag CopySmallArrayOp = 260+primOpTag CopySmallMutableArrayOp = 261+primOpTag CloneSmallArrayOp = 262+primOpTag CloneSmallMutableArrayOp = 263+primOpTag FreezeSmallArrayOp = 264+primOpTag ThawSmallArrayOp = 265+primOpTag CasSmallArrayOp = 266+primOpTag NewByteArrayOp_Char = 267+primOpTag NewPinnedByteArrayOp_Char = 268+primOpTag NewAlignedPinnedByteArrayOp_Char = 269+primOpTag MutableByteArrayIsPinnedOp = 270+primOpTag ByteArrayIsPinnedOp = 271+primOpTag ByteArrayContents_Char = 272+primOpTag SameMutableByteArrayOp = 273+primOpTag ShrinkMutableByteArrayOp_Char = 274+primOpTag ResizeMutableByteArrayOp_Char = 275+primOpTag UnsafeFreezeByteArrayOp = 276+primOpTag SizeofByteArrayOp = 277+primOpTag SizeofMutableByteArrayOp = 278+primOpTag GetSizeofMutableByteArrayOp = 279+primOpTag IndexByteArrayOp_Char = 280+primOpTag IndexByteArrayOp_WideChar = 281+primOpTag IndexByteArrayOp_Int = 282+primOpTag IndexByteArrayOp_Word = 283+primOpTag IndexByteArrayOp_Addr = 284+primOpTag IndexByteArrayOp_Float = 285+primOpTag IndexByteArrayOp_Double = 286+primOpTag IndexByteArrayOp_StablePtr = 287+primOpTag IndexByteArrayOp_Int8 = 288+primOpTag IndexByteArrayOp_Int16 = 289+primOpTag IndexByteArrayOp_Int32 = 290+primOpTag IndexByteArrayOp_Int64 = 291+primOpTag IndexByteArrayOp_Word8 = 292+primOpTag IndexByteArrayOp_Word16 = 293+primOpTag IndexByteArrayOp_Word32 = 294+primOpTag IndexByteArrayOp_Word64 = 295+primOpTag IndexByteArrayOp_Word8AsChar = 296+primOpTag IndexByteArrayOp_Word8AsWideChar = 297+primOpTag IndexByteArrayOp_Word8AsInt = 298+primOpTag IndexByteArrayOp_Word8AsWord = 299+primOpTag IndexByteArrayOp_Word8AsAddr = 300+primOpTag IndexByteArrayOp_Word8AsFloat = 301+primOpTag IndexByteArrayOp_Word8AsDouble = 302+primOpTag IndexByteArrayOp_Word8AsStablePtr = 303+primOpTag IndexByteArrayOp_Word8AsInt16 = 304+primOpTag IndexByteArrayOp_Word8AsInt32 = 305+primOpTag IndexByteArrayOp_Word8AsInt64 = 306+primOpTag IndexByteArrayOp_Word8AsWord16 = 307+primOpTag IndexByteArrayOp_Word8AsWord32 = 308+primOpTag IndexByteArrayOp_Word8AsWord64 = 309+primOpTag ReadByteArrayOp_Char = 310+primOpTag ReadByteArrayOp_WideChar = 311+primOpTag ReadByteArrayOp_Int = 312+primOpTag ReadByteArrayOp_Word = 313+primOpTag ReadByteArrayOp_Addr = 314+primOpTag ReadByteArrayOp_Float = 315+primOpTag ReadByteArrayOp_Double = 316+primOpTag ReadByteArrayOp_StablePtr = 317+primOpTag ReadByteArrayOp_Int8 = 318+primOpTag ReadByteArrayOp_Int16 = 319+primOpTag ReadByteArrayOp_Int32 = 320+primOpTag ReadByteArrayOp_Int64 = 321+primOpTag ReadByteArrayOp_Word8 = 322+primOpTag ReadByteArrayOp_Word16 = 323+primOpTag ReadByteArrayOp_Word32 = 324+primOpTag ReadByteArrayOp_Word64 = 325+primOpTag ReadByteArrayOp_Word8AsChar = 326+primOpTag ReadByteArrayOp_Word8AsWideChar = 327+primOpTag ReadByteArrayOp_Word8AsInt = 328+primOpTag ReadByteArrayOp_Word8AsWord = 329+primOpTag ReadByteArrayOp_Word8AsAddr = 330+primOpTag ReadByteArrayOp_Word8AsFloat = 331+primOpTag ReadByteArrayOp_Word8AsDouble = 332+primOpTag ReadByteArrayOp_Word8AsStablePtr = 333+primOpTag ReadByteArrayOp_Word8AsInt16 = 334+primOpTag ReadByteArrayOp_Word8AsInt32 = 335+primOpTag ReadByteArrayOp_Word8AsInt64 = 336+primOpTag ReadByteArrayOp_Word8AsWord16 = 337+primOpTag ReadByteArrayOp_Word8AsWord32 = 338+primOpTag ReadByteArrayOp_Word8AsWord64 = 339+primOpTag WriteByteArrayOp_Char = 340+primOpTag WriteByteArrayOp_WideChar = 341+primOpTag WriteByteArrayOp_Int = 342+primOpTag WriteByteArrayOp_Word = 343+primOpTag WriteByteArrayOp_Addr = 344+primOpTag WriteByteArrayOp_Float = 345+primOpTag WriteByteArrayOp_Double = 346+primOpTag WriteByteArrayOp_StablePtr = 347+primOpTag WriteByteArrayOp_Int8 = 348+primOpTag WriteByteArrayOp_Int16 = 349+primOpTag WriteByteArrayOp_Int32 = 350+primOpTag WriteByteArrayOp_Int64 = 351+primOpTag WriteByteArrayOp_Word8 = 352+primOpTag WriteByteArrayOp_Word16 = 353+primOpTag WriteByteArrayOp_Word32 = 354+primOpTag WriteByteArrayOp_Word64 = 355+primOpTag WriteByteArrayOp_Word8AsChar = 356+primOpTag WriteByteArrayOp_Word8AsWideChar = 357+primOpTag WriteByteArrayOp_Word8AsInt = 358+primOpTag WriteByteArrayOp_Word8AsWord = 359+primOpTag WriteByteArrayOp_Word8AsAddr = 360+primOpTag WriteByteArrayOp_Word8AsFloat = 361+primOpTag WriteByteArrayOp_Word8AsDouble = 362+primOpTag WriteByteArrayOp_Word8AsStablePtr = 363+primOpTag WriteByteArrayOp_Word8AsInt16 = 364+primOpTag WriteByteArrayOp_Word8AsInt32 = 365+primOpTag WriteByteArrayOp_Word8AsInt64 = 366+primOpTag WriteByteArrayOp_Word8AsWord16 = 367+primOpTag WriteByteArrayOp_Word8AsWord32 = 368+primOpTag WriteByteArrayOp_Word8AsWord64 = 369+primOpTag CompareByteArraysOp = 370+primOpTag CopyByteArrayOp = 371+primOpTag CopyMutableByteArrayOp = 372+primOpTag CopyByteArrayToAddrOp = 373+primOpTag CopyMutableByteArrayToAddrOp = 374+primOpTag CopyAddrToByteArrayOp = 375+primOpTag SetByteArrayOp = 376+primOpTag AtomicReadByteArrayOp_Int = 377+primOpTag AtomicWriteByteArrayOp_Int = 378+primOpTag CasByteArrayOp_Int = 379+primOpTag FetchAddByteArrayOp_Int = 380+primOpTag FetchSubByteArrayOp_Int = 381+primOpTag FetchAndByteArrayOp_Int = 382+primOpTag FetchNandByteArrayOp_Int = 383+primOpTag FetchOrByteArrayOp_Int = 384+primOpTag FetchXorByteArrayOp_Int = 385+primOpTag NewArrayArrayOp = 386+primOpTag SameMutableArrayArrayOp = 387+primOpTag UnsafeFreezeArrayArrayOp = 388+primOpTag SizeofArrayArrayOp = 389+primOpTag SizeofMutableArrayArrayOp = 390+primOpTag IndexArrayArrayOp_ByteArray = 391+primOpTag IndexArrayArrayOp_ArrayArray = 392+primOpTag ReadArrayArrayOp_ByteArray = 393+primOpTag ReadArrayArrayOp_MutableByteArray = 394+primOpTag ReadArrayArrayOp_ArrayArray = 395+primOpTag ReadArrayArrayOp_MutableArrayArray = 396+primOpTag WriteArrayArrayOp_ByteArray = 397+primOpTag WriteArrayArrayOp_MutableByteArray = 398+primOpTag WriteArrayArrayOp_ArrayArray = 399+primOpTag WriteArrayArrayOp_MutableArrayArray = 400+primOpTag CopyArrayArrayOp = 401+primOpTag CopyMutableArrayArrayOp = 402+primOpTag AddrAddOp = 403+primOpTag AddrSubOp = 404+primOpTag AddrRemOp = 405+primOpTag AddrToIntOp = 406+primOpTag IntToAddrOp = 407+primOpTag AddrGtOp = 408+primOpTag AddrGeOp = 409+primOpTag AddrEqOp = 410+primOpTag AddrNeOp = 411+primOpTag AddrLtOp = 412+primOpTag AddrLeOp = 413+primOpTag IndexOffAddrOp_Char = 414+primOpTag IndexOffAddrOp_WideChar = 415+primOpTag IndexOffAddrOp_Int = 416+primOpTag IndexOffAddrOp_Word = 417+primOpTag IndexOffAddrOp_Addr = 418+primOpTag IndexOffAddrOp_Float = 419+primOpTag IndexOffAddrOp_Double = 420+primOpTag IndexOffAddrOp_StablePtr = 421+primOpTag IndexOffAddrOp_Int8 = 422+primOpTag IndexOffAddrOp_Int16 = 423+primOpTag IndexOffAddrOp_Int32 = 424+primOpTag IndexOffAddrOp_Int64 = 425+primOpTag IndexOffAddrOp_Word8 = 426+primOpTag IndexOffAddrOp_Word16 = 427+primOpTag IndexOffAddrOp_Word32 = 428+primOpTag IndexOffAddrOp_Word64 = 429+primOpTag ReadOffAddrOp_Char = 430+primOpTag ReadOffAddrOp_WideChar = 431+primOpTag ReadOffAddrOp_Int = 432+primOpTag ReadOffAddrOp_Word = 433+primOpTag ReadOffAddrOp_Addr = 434+primOpTag ReadOffAddrOp_Float = 435+primOpTag ReadOffAddrOp_Double = 436+primOpTag ReadOffAddrOp_StablePtr = 437+primOpTag ReadOffAddrOp_Int8 = 438+primOpTag ReadOffAddrOp_Int16 = 439+primOpTag ReadOffAddrOp_Int32 = 440+primOpTag ReadOffAddrOp_Int64 = 441+primOpTag ReadOffAddrOp_Word8 = 442+primOpTag ReadOffAddrOp_Word16 = 443+primOpTag ReadOffAddrOp_Word32 = 444+primOpTag ReadOffAddrOp_Word64 = 445+primOpTag WriteOffAddrOp_Char = 446+primOpTag WriteOffAddrOp_WideChar = 447+primOpTag WriteOffAddrOp_Int = 448+primOpTag WriteOffAddrOp_Word = 449+primOpTag WriteOffAddrOp_Addr = 450+primOpTag WriteOffAddrOp_Float = 451+primOpTag WriteOffAddrOp_Double = 452+primOpTag WriteOffAddrOp_StablePtr = 453+primOpTag WriteOffAddrOp_Int8 = 454+primOpTag WriteOffAddrOp_Int16 = 455+primOpTag WriteOffAddrOp_Int32 = 456+primOpTag WriteOffAddrOp_Int64 = 457+primOpTag WriteOffAddrOp_Word8 = 458+primOpTag WriteOffAddrOp_Word16 = 459+primOpTag WriteOffAddrOp_Word32 = 460+primOpTag WriteOffAddrOp_Word64 = 461+primOpTag InterlockedExchange_Addr = 462+primOpTag InterlockedExchange_Word = 463+primOpTag CasAddrOp_Addr = 464+primOpTag CasAddrOp_Word = 465+primOpTag FetchAddAddrOp_Word = 466+primOpTag FetchSubAddrOp_Word = 467+primOpTag FetchAndAddrOp_Word = 468+primOpTag FetchNandAddrOp_Word = 469+primOpTag FetchOrAddrOp_Word = 470+primOpTag FetchXorAddrOp_Word = 471+primOpTag AtomicReadAddrOp_Word = 472+primOpTag AtomicWriteAddrOp_Word = 473+primOpTag NewMutVarOp = 474+primOpTag ReadMutVarOp = 475+primOpTag WriteMutVarOp = 476+primOpTag SameMutVarOp = 477+primOpTag AtomicModifyMutVar2Op = 478+primOpTag AtomicModifyMutVar_Op = 479+primOpTag CasMutVarOp = 480+primOpTag CatchOp = 481+primOpTag RaiseOp = 482+primOpTag RaiseIOOp = 483+primOpTag MaskAsyncExceptionsOp = 484+primOpTag MaskUninterruptibleOp = 485+primOpTag UnmaskAsyncExceptionsOp = 486+primOpTag MaskStatus = 487+primOpTag AtomicallyOp = 488+primOpTag RetryOp = 489+primOpTag CatchRetryOp = 490+primOpTag CatchSTMOp = 491+primOpTag NewTVarOp = 492+primOpTag ReadTVarOp = 493+primOpTag ReadTVarIOOp = 494+primOpTag WriteTVarOp = 495+primOpTag SameTVarOp = 496+primOpTag NewMVarOp = 497+primOpTag TakeMVarOp = 498+primOpTag TryTakeMVarOp = 499+primOpTag PutMVarOp = 500+primOpTag TryPutMVarOp = 501+primOpTag ReadMVarOp = 502+primOpTag TryReadMVarOp = 503+primOpTag SameMVarOp = 504+primOpTag IsEmptyMVarOp = 505+primOpTag NewIOPortrOp = 506+primOpTag ReadIOPortOp = 507+primOpTag WriteIOPortOp = 508+primOpTag SameIOPortOp = 509+primOpTag DelayOp = 510+primOpTag WaitReadOp = 511+primOpTag WaitWriteOp = 512+primOpTag ForkOp = 513+primOpTag ForkOnOp = 514+primOpTag KillThreadOp = 515+primOpTag YieldOp = 516+primOpTag MyThreadIdOp = 517+primOpTag LabelThreadOp = 518+primOpTag IsCurrentThreadBoundOp = 519+primOpTag NoDuplicateOp = 520+primOpTag ThreadStatusOp = 521+primOpTag MkWeakOp = 522+primOpTag MkWeakNoFinalizerOp = 523+primOpTag AddCFinalizerToWeakOp = 524+primOpTag DeRefWeakOp = 525+primOpTag FinalizeWeakOp = 526+primOpTag TouchOp = 527+primOpTag MakeStablePtrOp = 528+primOpTag DeRefStablePtrOp = 529+primOpTag EqStablePtrOp = 530+primOpTag MakeStableNameOp = 531+primOpTag EqStableNameOp = 532+primOpTag StableNameToIntOp = 533+primOpTag CompactNewOp = 534+primOpTag CompactResizeOp = 535+primOpTag CompactContainsOp = 536+primOpTag CompactContainsAnyOp = 537+primOpTag CompactGetFirstBlockOp = 538+primOpTag CompactGetNextBlockOp = 539+primOpTag CompactAllocateBlockOp = 540+primOpTag CompactFixupPointersOp = 541+primOpTag CompactAdd = 542+primOpTag CompactAddWithSharing = 543+primOpTag CompactSize = 544+primOpTag ReallyUnsafePtrEqualityOp = 545+primOpTag ParOp = 546+primOpTag SparkOp = 547+primOpTag SeqOp = 548+primOpTag GetSparkOp = 549+primOpTag NumSparks = 550+primOpTag DataToTagOp = 551+primOpTag TagToEnumOp = 552+primOpTag AddrToAnyOp = 553+primOpTag AnyToAddrOp = 554+primOpTag MkApUpd0_Op = 555+primOpTag NewBCOOp = 556+primOpTag UnpackClosureOp = 557+primOpTag ClosureSizeOp = 558+primOpTag GetApStackValOp = 559+primOpTag GetCCSOfOp = 560+primOpTag GetCurrentCCSOp = 561+primOpTag ClearCCSOp = 562+primOpTag TraceEventOp = 563+primOpTag TraceEventBinaryOp = 564+primOpTag TraceMarkerOp = 565+primOpTag SetThreadAllocationCounter = 566+primOpTag (VecBroadcastOp IntVec 16 W8) = 567+primOpTag (VecBroadcastOp IntVec 8 W16) = 568+primOpTag (VecBroadcastOp IntVec 4 W32) = 569+primOpTag (VecBroadcastOp IntVec 2 W64) = 570+primOpTag (VecBroadcastOp IntVec 32 W8) = 571+primOpTag (VecBroadcastOp IntVec 16 W16) = 572+primOpTag (VecBroadcastOp IntVec 8 W32) = 573+primOpTag (VecBroadcastOp IntVec 4 W64) = 574+primOpTag (VecBroadcastOp IntVec 64 W8) = 575+primOpTag (VecBroadcastOp IntVec 32 W16) = 576+primOpTag (VecBroadcastOp IntVec 16 W32) = 577+primOpTag (VecBroadcastOp IntVec 8 W64) = 578+primOpTag (VecBroadcastOp WordVec 16 W8) = 579+primOpTag (VecBroadcastOp WordVec 8 W16) = 580+primOpTag (VecBroadcastOp WordVec 4 W32) = 581+primOpTag (VecBroadcastOp WordVec 2 W64) = 582+primOpTag (VecBroadcastOp WordVec 32 W8) = 583+primOpTag (VecBroadcastOp WordVec 16 W16) = 584+primOpTag (VecBroadcastOp WordVec 8 W32) = 585+primOpTag (VecBroadcastOp WordVec 4 W64) = 586+primOpTag (VecBroadcastOp WordVec 64 W8) = 587+primOpTag (VecBroadcastOp WordVec 32 W16) = 588+primOpTag (VecBroadcastOp WordVec 16 W32) = 589+primOpTag (VecBroadcastOp WordVec 8 W64) = 590+primOpTag (VecBroadcastOp FloatVec 4 W32) = 591+primOpTag (VecBroadcastOp FloatVec 2 W64) = 592+primOpTag (VecBroadcastOp FloatVec 8 W32) = 593+primOpTag (VecBroadcastOp FloatVec 4 W64) = 594+primOpTag (VecBroadcastOp FloatVec 16 W32) = 595+primOpTag (VecBroadcastOp FloatVec 8 W64) = 596+primOpTag (VecPackOp IntVec 16 W8) = 597+primOpTag (VecPackOp IntVec 8 W16) = 598+primOpTag (VecPackOp IntVec 4 W32) = 599+primOpTag (VecPackOp IntVec 2 W64) = 600+primOpTag (VecPackOp IntVec 32 W8) = 601+primOpTag (VecPackOp IntVec 16 W16) = 602+primOpTag (VecPackOp IntVec 8 W32) = 603+primOpTag (VecPackOp IntVec 4 W64) = 604+primOpTag (VecPackOp IntVec 64 W8) = 605+primOpTag (VecPackOp IntVec 32 W16) = 606+primOpTag (VecPackOp IntVec 16 W32) = 607+primOpTag (VecPackOp IntVec 8 W64) = 608+primOpTag (VecPackOp WordVec 16 W8) = 609+primOpTag (VecPackOp WordVec 8 W16) = 610+primOpTag (VecPackOp WordVec 4 W32) = 611+primOpTag (VecPackOp WordVec 2 W64) = 612+primOpTag (VecPackOp WordVec 32 W8) = 613+primOpTag (VecPackOp WordVec 16 W16) = 614+primOpTag (VecPackOp WordVec 8 W32) = 615+primOpTag (VecPackOp WordVec 4 W64) = 616+primOpTag (VecPackOp WordVec 64 W8) = 617+primOpTag (VecPackOp WordVec 32 W16) = 618+primOpTag (VecPackOp WordVec 16 W32) = 619+primOpTag (VecPackOp WordVec 8 W64) = 620+primOpTag (VecPackOp FloatVec 4 W32) = 621+primOpTag (VecPackOp FloatVec 2 W64) = 622+primOpTag (VecPackOp FloatVec 8 W32) = 623+primOpTag (VecPackOp FloatVec 4 W64) = 624+primOpTag (VecPackOp FloatVec 16 W32) = 625+primOpTag (VecPackOp FloatVec 8 W64) = 626+primOpTag (VecUnpackOp IntVec 16 W8) = 627+primOpTag (VecUnpackOp IntVec 8 W16) = 628+primOpTag (VecUnpackOp IntVec 4 W32) = 629+primOpTag (VecUnpackOp IntVec 2 W64) = 630+primOpTag (VecUnpackOp IntVec 32 W8) = 631+primOpTag (VecUnpackOp IntVec 16 W16) = 632+primOpTag (VecUnpackOp IntVec 8 W32) = 633+primOpTag (VecUnpackOp IntVec 4 W64) = 634+primOpTag (VecUnpackOp IntVec 64 W8) = 635+primOpTag (VecUnpackOp IntVec 32 W16) = 636+primOpTag (VecUnpackOp IntVec 16 W32) = 637+primOpTag (VecUnpackOp IntVec 8 W64) = 638+primOpTag (VecUnpackOp WordVec 16 W8) = 639+primOpTag (VecUnpackOp WordVec 8 W16) = 640+primOpTag (VecUnpackOp WordVec 4 W32) = 641+primOpTag (VecUnpackOp WordVec 2 W64) = 642+primOpTag (VecUnpackOp WordVec 32 W8) = 643+primOpTag (VecUnpackOp WordVec 16 W16) = 644+primOpTag (VecUnpackOp WordVec 8 W32) = 645+primOpTag (VecUnpackOp WordVec 4 W64) = 646+primOpTag (VecUnpackOp WordVec 64 W8) = 647+primOpTag (VecUnpackOp WordVec 32 W16) = 648+primOpTag (VecUnpackOp WordVec 16 W32) = 649+primOpTag (VecUnpackOp WordVec 8 W64) = 650+primOpTag (VecUnpackOp FloatVec 4 W32) = 651+primOpTag (VecUnpackOp FloatVec 2 W64) = 652+primOpTag (VecUnpackOp FloatVec 8 W32) = 653+primOpTag (VecUnpackOp FloatVec 4 W64) = 654+primOpTag (VecUnpackOp FloatVec 16 W32) = 655+primOpTag (VecUnpackOp FloatVec 8 W64) = 656+primOpTag (VecInsertOp IntVec 16 W8) = 657+primOpTag (VecInsertOp IntVec 8 W16) = 658+primOpTag (VecInsertOp IntVec 4 W32) = 659+primOpTag (VecInsertOp IntVec 2 W64) = 660+primOpTag (VecInsertOp IntVec 32 W8) = 661+primOpTag (VecInsertOp IntVec 16 W16) = 662+primOpTag (VecInsertOp IntVec 8 W32) = 663+primOpTag (VecInsertOp IntVec 4 W64) = 664+primOpTag (VecInsertOp IntVec 64 W8) = 665+primOpTag (VecInsertOp IntVec 32 W16) = 666+primOpTag (VecInsertOp IntVec 16 W32) = 667+primOpTag (VecInsertOp IntVec 8 W64) = 668+primOpTag (VecInsertOp WordVec 16 W8) = 669+primOpTag (VecInsertOp WordVec 8 W16) = 670+primOpTag (VecInsertOp WordVec 4 W32) = 671+primOpTag (VecInsertOp WordVec 2 W64) = 672+primOpTag (VecInsertOp WordVec 32 W8) = 673+primOpTag (VecInsertOp WordVec 16 W16) = 674+primOpTag (VecInsertOp WordVec 8 W32) = 675+primOpTag (VecInsertOp WordVec 4 W64) = 676+primOpTag (VecInsertOp WordVec 64 W8) = 677+primOpTag (VecInsertOp WordVec 32 W16) = 678+primOpTag (VecInsertOp WordVec 16 W32) = 679+primOpTag (VecInsertOp WordVec 8 W64) = 680+primOpTag (VecInsertOp FloatVec 4 W32) = 681+primOpTag (VecInsertOp FloatVec 2 W64) = 682+primOpTag (VecInsertOp FloatVec 8 W32) = 683+primOpTag (VecInsertOp FloatVec 4 W64) = 684+primOpTag (VecInsertOp FloatVec 16 W32) = 685+primOpTag (VecInsertOp FloatVec 8 W64) = 686+primOpTag (VecAddOp IntVec 16 W8) = 687+primOpTag (VecAddOp IntVec 8 W16) = 688+primOpTag (VecAddOp IntVec 4 W32) = 689+primOpTag (VecAddOp IntVec 2 W64) = 690+primOpTag (VecAddOp IntVec 32 W8) = 691+primOpTag (VecAddOp IntVec 16 W16) = 692+primOpTag (VecAddOp IntVec 8 W32) = 693+primOpTag (VecAddOp IntVec 4 W64) = 694+primOpTag (VecAddOp IntVec 64 W8) = 695+primOpTag (VecAddOp IntVec 32 W16) = 696+primOpTag (VecAddOp IntVec 16 W32) = 697+primOpTag (VecAddOp IntVec 8 W64) = 698+primOpTag (VecAddOp WordVec 16 W8) = 699+primOpTag (VecAddOp WordVec 8 W16) = 700+primOpTag (VecAddOp WordVec 4 W32) = 701+primOpTag (VecAddOp WordVec 2 W64) = 702+primOpTag (VecAddOp WordVec 32 W8) = 703+primOpTag (VecAddOp WordVec 16 W16) = 704+primOpTag (VecAddOp WordVec 8 W32) = 705+primOpTag (VecAddOp WordVec 4 W64) = 706+primOpTag (VecAddOp WordVec 64 W8) = 707+primOpTag (VecAddOp WordVec 32 W16) = 708+primOpTag (VecAddOp WordVec 16 W32) = 709+primOpTag (VecAddOp WordVec 8 W64) = 710+primOpTag (VecAddOp FloatVec 4 W32) = 711+primOpTag (VecAddOp FloatVec 2 W64) = 712+primOpTag (VecAddOp FloatVec 8 W32) = 713+primOpTag (VecAddOp FloatVec 4 W64) = 714+primOpTag (VecAddOp FloatVec 16 W32) = 715+primOpTag (VecAddOp FloatVec 8 W64) = 716+primOpTag (VecSubOp IntVec 16 W8) = 717+primOpTag (VecSubOp IntVec 8 W16) = 718+primOpTag (VecSubOp IntVec 4 W32) = 719+primOpTag (VecSubOp IntVec 2 W64) = 720+primOpTag (VecSubOp IntVec 32 W8) = 721+primOpTag (VecSubOp IntVec 16 W16) = 722+primOpTag (VecSubOp IntVec 8 W32) = 723+primOpTag (VecSubOp IntVec 4 W64) = 724+primOpTag (VecSubOp IntVec 64 W8) = 725+primOpTag (VecSubOp IntVec 32 W16) = 726+primOpTag (VecSubOp IntVec 16 W32) = 727+primOpTag (VecSubOp IntVec 8 W64) = 728+primOpTag (VecSubOp WordVec 16 W8) = 729+primOpTag (VecSubOp WordVec 8 W16) = 730+primOpTag (VecSubOp WordVec 4 W32) = 731+primOpTag (VecSubOp WordVec 2 W64) = 732+primOpTag (VecSubOp WordVec 32 W8) = 733+primOpTag (VecSubOp WordVec 16 W16) = 734+primOpTag (VecSubOp WordVec 8 W32) = 735+primOpTag (VecSubOp WordVec 4 W64) = 736+primOpTag (VecSubOp WordVec 64 W8) = 737+primOpTag (VecSubOp WordVec 32 W16) = 738+primOpTag (VecSubOp WordVec 16 W32) = 739+primOpTag (VecSubOp WordVec 8 W64) = 740+primOpTag (VecSubOp FloatVec 4 W32) = 741+primOpTag (VecSubOp FloatVec 2 W64) = 742+primOpTag (VecSubOp FloatVec 8 W32) = 743+primOpTag (VecSubOp FloatVec 4 W64) = 744+primOpTag (VecSubOp FloatVec 16 W32) = 745+primOpTag (VecSubOp FloatVec 8 W64) = 746+primOpTag (VecMulOp IntVec 16 W8) = 747+primOpTag (VecMulOp IntVec 8 W16) = 748+primOpTag (VecMulOp IntVec 4 W32) = 749+primOpTag (VecMulOp IntVec 2 W64) = 750+primOpTag (VecMulOp IntVec 32 W8) = 751+primOpTag (VecMulOp IntVec 16 W16) = 752+primOpTag (VecMulOp IntVec 8 W32) = 753+primOpTag (VecMulOp IntVec 4 W64) = 754+primOpTag (VecMulOp IntVec 64 W8) = 755+primOpTag (VecMulOp IntVec 32 W16) = 756+primOpTag (VecMulOp IntVec 16 W32) = 757+primOpTag (VecMulOp IntVec 8 W64) = 758+primOpTag (VecMulOp WordVec 16 W8) = 759+primOpTag (VecMulOp WordVec 8 W16) = 760+primOpTag (VecMulOp WordVec 4 W32) = 761+primOpTag (VecMulOp WordVec 2 W64) = 762+primOpTag (VecMulOp WordVec 32 W8) = 763+primOpTag (VecMulOp WordVec 16 W16) = 764+primOpTag (VecMulOp WordVec 8 W32) = 765+primOpTag (VecMulOp WordVec 4 W64) = 766+primOpTag (VecMulOp WordVec 64 W8) = 767+primOpTag (VecMulOp WordVec 32 W16) = 768+primOpTag (VecMulOp WordVec 16 W32) = 769+primOpTag (VecMulOp WordVec 8 W64) = 770+primOpTag (VecMulOp FloatVec 4 W32) = 771+primOpTag (VecMulOp FloatVec 2 W64) = 772+primOpTag (VecMulOp FloatVec 8 W32) = 773+primOpTag (VecMulOp FloatVec 4 W64) = 774+primOpTag (VecMulOp FloatVec 16 W32) = 775+primOpTag (VecMulOp FloatVec 8 W64) = 776+primOpTag (VecDivOp FloatVec 4 W32) = 777+primOpTag (VecDivOp FloatVec 2 W64) = 778+primOpTag (VecDivOp FloatVec 8 W32) = 779+primOpTag (VecDivOp FloatVec 4 W64) = 780+primOpTag (VecDivOp FloatVec 16 W32) = 781+primOpTag (VecDivOp FloatVec 8 W64) = 782+primOpTag (VecQuotOp IntVec 16 W8) = 783+primOpTag (VecQuotOp IntVec 8 W16) = 784+primOpTag (VecQuotOp IntVec 4 W32) = 785+primOpTag (VecQuotOp IntVec 2 W64) = 786+primOpTag (VecQuotOp IntVec 32 W8) = 787+primOpTag (VecQuotOp IntVec 16 W16) = 788+primOpTag (VecQuotOp IntVec 8 W32) = 789+primOpTag (VecQuotOp IntVec 4 W64) = 790+primOpTag (VecQuotOp IntVec 64 W8) = 791+primOpTag (VecQuotOp IntVec 32 W16) = 792+primOpTag (VecQuotOp IntVec 16 W32) = 793+primOpTag (VecQuotOp IntVec 8 W64) = 794+primOpTag (VecQuotOp WordVec 16 W8) = 795+primOpTag (VecQuotOp WordVec 8 W16) = 796+primOpTag (VecQuotOp WordVec 4 W32) = 797+primOpTag (VecQuotOp WordVec 2 W64) = 798+primOpTag (VecQuotOp WordVec 32 W8) = 799+primOpTag (VecQuotOp WordVec 16 W16) = 800+primOpTag (VecQuotOp WordVec 8 W32) = 801+primOpTag (VecQuotOp WordVec 4 W64) = 802+primOpTag (VecQuotOp WordVec 64 W8) = 803+primOpTag (VecQuotOp WordVec 32 W16) = 804+primOpTag (VecQuotOp WordVec 16 W32) = 805+primOpTag (VecQuotOp WordVec 8 W64) = 806+primOpTag (VecRemOp IntVec 16 W8) = 807+primOpTag (VecRemOp IntVec 8 W16) = 808+primOpTag (VecRemOp IntVec 4 W32) = 809+primOpTag (VecRemOp IntVec 2 W64) = 810+primOpTag (VecRemOp IntVec 32 W8) = 811+primOpTag (VecRemOp IntVec 16 W16) = 812+primOpTag (VecRemOp IntVec 8 W32) = 813+primOpTag (VecRemOp IntVec 4 W64) = 814+primOpTag (VecRemOp IntVec 64 W8) = 815+primOpTag (VecRemOp IntVec 32 W16) = 816+primOpTag (VecRemOp IntVec 16 W32) = 817+primOpTag (VecRemOp IntVec 8 W64) = 818+primOpTag (VecRemOp WordVec 16 W8) = 819+primOpTag (VecRemOp WordVec 8 W16) = 820+primOpTag (VecRemOp WordVec 4 W32) = 821+primOpTag (VecRemOp WordVec 2 W64) = 822+primOpTag (VecRemOp WordVec 32 W8) = 823+primOpTag (VecRemOp WordVec 16 W16) = 824+primOpTag (VecRemOp WordVec 8 W32) = 825+primOpTag (VecRemOp WordVec 4 W64) = 826+primOpTag (VecRemOp WordVec 64 W8) = 827+primOpTag (VecRemOp WordVec 32 W16) = 828+primOpTag (VecRemOp WordVec 16 W32) = 829+primOpTag (VecRemOp WordVec 8 W64) = 830+primOpTag (VecNegOp IntVec 16 W8) = 831+primOpTag (VecNegOp IntVec 8 W16) = 832+primOpTag (VecNegOp IntVec 4 W32) = 833+primOpTag (VecNegOp IntVec 2 W64) = 834+primOpTag (VecNegOp IntVec 32 W8) = 835+primOpTag (VecNegOp IntVec 16 W16) = 836+primOpTag (VecNegOp IntVec 8 W32) = 837+primOpTag (VecNegOp IntVec 4 W64) = 838+primOpTag (VecNegOp IntVec 64 W8) = 839+primOpTag (VecNegOp IntVec 32 W16) = 840+primOpTag (VecNegOp IntVec 16 W32) = 841+primOpTag (VecNegOp IntVec 8 W64) = 842+primOpTag (VecNegOp FloatVec 4 W32) = 843+primOpTag (VecNegOp FloatVec 2 W64) = 844+primOpTag (VecNegOp FloatVec 8 W32) = 845+primOpTag (VecNegOp FloatVec 4 W64) = 846+primOpTag (VecNegOp FloatVec 16 W32) = 847+primOpTag (VecNegOp FloatVec 8 W64) = 848+primOpTag (VecIndexByteArrayOp IntVec 16 W8) = 849+primOpTag (VecIndexByteArrayOp IntVec 8 W16) = 850+primOpTag (VecIndexByteArrayOp IntVec 4 W32) = 851+primOpTag (VecIndexByteArrayOp IntVec 2 W64) = 852+primOpTag (VecIndexByteArrayOp IntVec 32 W8) = 853+primOpTag (VecIndexByteArrayOp IntVec 16 W16) = 854+primOpTag (VecIndexByteArrayOp IntVec 8 W32) = 855+primOpTag (VecIndexByteArrayOp IntVec 4 W64) = 856+primOpTag (VecIndexByteArrayOp IntVec 64 W8) = 857+primOpTag (VecIndexByteArrayOp IntVec 32 W16) = 858+primOpTag (VecIndexByteArrayOp IntVec 16 W32) = 859+primOpTag (VecIndexByteArrayOp IntVec 8 W64) = 860+primOpTag (VecIndexByteArrayOp WordVec 16 W8) = 861+primOpTag (VecIndexByteArrayOp WordVec 8 W16) = 862+primOpTag (VecIndexByteArrayOp WordVec 4 W32) = 863+primOpTag (VecIndexByteArrayOp WordVec 2 W64) = 864+primOpTag (VecIndexByteArrayOp WordVec 32 W8) = 865+primOpTag (VecIndexByteArrayOp WordVec 16 W16) = 866+primOpTag (VecIndexByteArrayOp WordVec 8 W32) = 867+primOpTag (VecIndexByteArrayOp WordVec 4 W64) = 868+primOpTag (VecIndexByteArrayOp WordVec 64 W8) = 869+primOpTag (VecIndexByteArrayOp WordVec 32 W16) = 870+primOpTag (VecIndexByteArrayOp WordVec 16 W32) = 871+primOpTag (VecIndexByteArrayOp WordVec 8 W64) = 872+primOpTag (VecIndexByteArrayOp FloatVec 4 W32) = 873+primOpTag (VecIndexByteArrayOp FloatVec 2 W64) = 874+primOpTag (VecIndexByteArrayOp FloatVec 8 W32) = 875+primOpTag (VecIndexByteArrayOp FloatVec 4 W64) = 876+primOpTag (VecIndexByteArrayOp FloatVec 16 W32) = 877+primOpTag (VecIndexByteArrayOp FloatVec 8 W64) = 878+primOpTag (VecReadByteArrayOp IntVec 16 W8) = 879+primOpTag (VecReadByteArrayOp IntVec 8 W16) = 880+primOpTag (VecReadByteArrayOp IntVec 4 W32) = 881+primOpTag (VecReadByteArrayOp IntVec 2 W64) = 882+primOpTag (VecReadByteArrayOp IntVec 32 W8) = 883+primOpTag (VecReadByteArrayOp IntVec 16 W16) = 884+primOpTag (VecReadByteArrayOp IntVec 8 W32) = 885+primOpTag (VecReadByteArrayOp IntVec 4 W64) = 886+primOpTag (VecReadByteArrayOp IntVec 64 W8) = 887+primOpTag (VecReadByteArrayOp IntVec 32 W16) = 888+primOpTag (VecReadByteArrayOp IntVec 16 W32) = 889+primOpTag (VecReadByteArrayOp IntVec 8 W64) = 890+primOpTag (VecReadByteArrayOp WordVec 16 W8) = 891+primOpTag (VecReadByteArrayOp WordVec 8 W16) = 892+primOpTag (VecReadByteArrayOp WordVec 4 W32) = 893+primOpTag (VecReadByteArrayOp WordVec 2 W64) = 894+primOpTag (VecReadByteArrayOp WordVec 32 W8) = 895+primOpTag (VecReadByteArrayOp WordVec 16 W16) = 896+primOpTag (VecReadByteArrayOp WordVec 8 W32) = 897+primOpTag (VecReadByteArrayOp WordVec 4 W64) = 898+primOpTag (VecReadByteArrayOp WordVec 64 W8) = 899+primOpTag (VecReadByteArrayOp WordVec 32 W16) = 900+primOpTag (VecReadByteArrayOp WordVec 16 W32) = 901+primOpTag (VecReadByteArrayOp WordVec 8 W64) = 902+primOpTag (VecReadByteArrayOp FloatVec 4 W32) = 903+primOpTag (VecReadByteArrayOp FloatVec 2 W64) = 904+primOpTag (VecReadByteArrayOp FloatVec 8 W32) = 905+primOpTag (VecReadByteArrayOp FloatVec 4 W64) = 906+primOpTag (VecReadByteArrayOp FloatVec 16 W32) = 907+primOpTag (VecReadByteArrayOp FloatVec 8 W64) = 908+primOpTag (VecWriteByteArrayOp IntVec 16 W8) = 909+primOpTag (VecWriteByteArrayOp IntVec 8 W16) = 910+primOpTag (VecWriteByteArrayOp IntVec 4 W32) = 911+primOpTag (VecWriteByteArrayOp IntVec 2 W64) = 912+primOpTag (VecWriteByteArrayOp IntVec 32 W8) = 913+primOpTag (VecWriteByteArrayOp IntVec 16 W16) = 914+primOpTag (VecWriteByteArrayOp IntVec 8 W32) = 915+primOpTag (VecWriteByteArrayOp IntVec 4 W64) = 916+primOpTag (VecWriteByteArrayOp IntVec 64 W8) = 917+primOpTag (VecWriteByteArrayOp IntVec 32 W16) = 918+primOpTag (VecWriteByteArrayOp IntVec 16 W32) = 919+primOpTag (VecWriteByteArrayOp IntVec 8 W64) = 920+primOpTag (VecWriteByteArrayOp WordVec 16 W8) = 921+primOpTag (VecWriteByteArrayOp WordVec 8 W16) = 922+primOpTag (VecWriteByteArrayOp WordVec 4 W32) = 923+primOpTag (VecWriteByteArrayOp WordVec 2 W64) = 924+primOpTag (VecWriteByteArrayOp WordVec 32 W8) = 925+primOpTag (VecWriteByteArrayOp WordVec 16 W16) = 926+primOpTag (VecWriteByteArrayOp WordVec 8 W32) = 927+primOpTag (VecWriteByteArrayOp WordVec 4 W64) = 928+primOpTag (VecWriteByteArrayOp WordVec 64 W8) = 929+primOpTag (VecWriteByteArrayOp WordVec 32 W16) = 930+primOpTag (VecWriteByteArrayOp WordVec 16 W32) = 931+primOpTag (VecWriteByteArrayOp WordVec 8 W64) = 932+primOpTag (VecWriteByteArrayOp FloatVec 4 W32) = 933+primOpTag (VecWriteByteArrayOp FloatVec 2 W64) = 934+primOpTag (VecWriteByteArrayOp FloatVec 8 W32) = 935+primOpTag (VecWriteByteArrayOp FloatVec 4 W64) = 936+primOpTag (VecWriteByteArrayOp FloatVec 16 W32) = 937+primOpTag (VecWriteByteArrayOp FloatVec 8 W64) = 938+primOpTag (VecIndexOffAddrOp IntVec 16 W8) = 939+primOpTag (VecIndexOffAddrOp IntVec 8 W16) = 940+primOpTag (VecIndexOffAddrOp IntVec 4 W32) = 941+primOpTag (VecIndexOffAddrOp IntVec 2 W64) = 942+primOpTag (VecIndexOffAddrOp IntVec 32 W8) = 943+primOpTag (VecIndexOffAddrOp IntVec 16 W16) = 944+primOpTag (VecIndexOffAddrOp IntVec 8 W32) = 945+primOpTag (VecIndexOffAddrOp IntVec 4 W64) = 946+primOpTag (VecIndexOffAddrOp IntVec 64 W8) = 947+primOpTag (VecIndexOffAddrOp IntVec 32 W16) = 948+primOpTag (VecIndexOffAddrOp IntVec 16 W32) = 949+primOpTag (VecIndexOffAddrOp IntVec 8 W64) = 950+primOpTag (VecIndexOffAddrOp WordVec 16 W8) = 951+primOpTag (VecIndexOffAddrOp WordVec 8 W16) = 952+primOpTag (VecIndexOffAddrOp WordVec 4 W32) = 953+primOpTag (VecIndexOffAddrOp WordVec 2 W64) = 954+primOpTag (VecIndexOffAddrOp WordVec 32 W8) = 955+primOpTag (VecIndexOffAddrOp WordVec 16 W16) = 956+primOpTag (VecIndexOffAddrOp WordVec 8 W32) = 957+primOpTag (VecIndexOffAddrOp WordVec 4 W64) = 958+primOpTag (VecIndexOffAddrOp WordVec 64 W8) = 959+primOpTag (VecIndexOffAddrOp WordVec 32 W16) = 960+primOpTag (VecIndexOffAddrOp WordVec 16 W32) = 961+primOpTag (VecIndexOffAddrOp WordVec 8 W64) = 962+primOpTag (VecIndexOffAddrOp FloatVec 4 W32) = 963+primOpTag (VecIndexOffAddrOp FloatVec 2 W64) = 964+primOpTag (VecIndexOffAddrOp FloatVec 8 W32) = 965+primOpTag (VecIndexOffAddrOp FloatVec 4 W64) = 966+primOpTag (VecIndexOffAddrOp FloatVec 16 W32) = 967+primOpTag (VecIndexOffAddrOp FloatVec 8 W64) = 968+primOpTag (VecReadOffAddrOp IntVec 16 W8) = 969+primOpTag (VecReadOffAddrOp IntVec 8 W16) = 970+primOpTag (VecReadOffAddrOp IntVec 4 W32) = 971+primOpTag (VecReadOffAddrOp IntVec 2 W64) = 972+primOpTag (VecReadOffAddrOp IntVec 32 W8) = 973+primOpTag (VecReadOffAddrOp IntVec 16 W16) = 974+primOpTag (VecReadOffAddrOp IntVec 8 W32) = 975+primOpTag (VecReadOffAddrOp IntVec 4 W64) = 976+primOpTag (VecReadOffAddrOp IntVec 64 W8) = 977+primOpTag (VecReadOffAddrOp IntVec 32 W16) = 978+primOpTag (VecReadOffAddrOp IntVec 16 W32) = 979+primOpTag (VecReadOffAddrOp IntVec 8 W64) = 980+primOpTag (VecReadOffAddrOp WordVec 16 W8) = 981+primOpTag (VecReadOffAddrOp WordVec 8 W16) = 982+primOpTag (VecReadOffAddrOp WordVec 4 W32) = 983+primOpTag (VecReadOffAddrOp WordVec 2 W64) = 984+primOpTag (VecReadOffAddrOp WordVec 32 W8) = 985+primOpTag (VecReadOffAddrOp WordVec 16 W16) = 986+primOpTag (VecReadOffAddrOp WordVec 8 W32) = 987+primOpTag (VecReadOffAddrOp WordVec 4 W64) = 988+primOpTag (VecReadOffAddrOp WordVec 64 W8) = 989+primOpTag (VecReadOffAddrOp WordVec 32 W16) = 990+primOpTag (VecReadOffAddrOp WordVec 16 W32) = 991+primOpTag (VecReadOffAddrOp WordVec 8 W64) = 992+primOpTag (VecReadOffAddrOp FloatVec 4 W32) = 993+primOpTag (VecReadOffAddrOp FloatVec 2 W64) = 994+primOpTag (VecReadOffAddrOp FloatVec 8 W32) = 995+primOpTag (VecReadOffAddrOp FloatVec 4 W64) = 996+primOpTag (VecReadOffAddrOp FloatVec 16 W32) = 997+primOpTag (VecReadOffAddrOp FloatVec 8 W64) = 998+primOpTag (VecWriteOffAddrOp IntVec 16 W8) = 999+primOpTag (VecWriteOffAddrOp IntVec 8 W16) = 1000+primOpTag (VecWriteOffAddrOp IntVec 4 W32) = 1001+primOpTag (VecWriteOffAddrOp IntVec 2 W64) = 1002+primOpTag (VecWriteOffAddrOp IntVec 32 W8) = 1003+primOpTag (VecWriteOffAddrOp IntVec 16 W16) = 1004+primOpTag (VecWriteOffAddrOp IntVec 8 W32) = 1005+primOpTag (VecWriteOffAddrOp IntVec 4 W64) = 1006+primOpTag (VecWriteOffAddrOp IntVec 64 W8) = 1007+primOpTag (VecWriteOffAddrOp IntVec 32 W16) = 1008+primOpTag (VecWriteOffAddrOp IntVec 16 W32) = 1009+primOpTag (VecWriteOffAddrOp IntVec 8 W64) = 1010+primOpTag (VecWriteOffAddrOp WordVec 16 W8) = 1011+primOpTag (VecWriteOffAddrOp WordVec 8 W16) = 1012+primOpTag (VecWriteOffAddrOp WordVec 4 W32) = 1013+primOpTag (VecWriteOffAddrOp WordVec 2 W64) = 1014+primOpTag (VecWriteOffAddrOp WordVec 32 W8) = 1015+primOpTag (VecWriteOffAddrOp WordVec 16 W16) = 1016+primOpTag (VecWriteOffAddrOp WordVec 8 W32) = 1017+primOpTag (VecWriteOffAddrOp WordVec 4 W64) = 1018+primOpTag (VecWriteOffAddrOp WordVec 64 W8) = 1019+primOpTag (VecWriteOffAddrOp WordVec 32 W16) = 1020+primOpTag (VecWriteOffAddrOp WordVec 16 W32) = 1021+primOpTag (VecWriteOffAddrOp WordVec 8 W64) = 1022+primOpTag (VecWriteOffAddrOp FloatVec 4 W32) = 1023+primOpTag (VecWriteOffAddrOp FloatVec 2 W64) = 1024+primOpTag (VecWriteOffAddrOp FloatVec 8 W32) = 1025+primOpTag (VecWriteOffAddrOp FloatVec 4 W64) = 1026+primOpTag (VecWriteOffAddrOp FloatVec 16 W32) = 1027+primOpTag (VecWriteOffAddrOp FloatVec 8 W64) = 1028+primOpTag (VecIndexScalarByteArrayOp IntVec 16 W8) = 1029+primOpTag (VecIndexScalarByteArrayOp IntVec 8 W16) = 1030+primOpTag (VecIndexScalarByteArrayOp IntVec 4 W32) = 1031+primOpTag (VecIndexScalarByteArrayOp IntVec 2 W64) = 1032+primOpTag (VecIndexScalarByteArrayOp IntVec 32 W8) = 1033+primOpTag (VecIndexScalarByteArrayOp IntVec 16 W16) = 1034+primOpTag (VecIndexScalarByteArrayOp IntVec 8 W32) = 1035+primOpTag (VecIndexScalarByteArrayOp IntVec 4 W64) = 1036+primOpTag (VecIndexScalarByteArrayOp IntVec 64 W8) = 1037+primOpTag (VecIndexScalarByteArrayOp IntVec 32 W16) = 1038+primOpTag (VecIndexScalarByteArrayOp IntVec 16 W32) = 1039+primOpTag (VecIndexScalarByteArrayOp IntVec 8 W64) = 1040+primOpTag (VecIndexScalarByteArrayOp WordVec 16 W8) = 1041+primOpTag (VecIndexScalarByteArrayOp WordVec 8 W16) = 1042+primOpTag (VecIndexScalarByteArrayOp WordVec 4 W32) = 1043+primOpTag (VecIndexScalarByteArrayOp WordVec 2 W64) = 1044+primOpTag (VecIndexScalarByteArrayOp WordVec 32 W8) = 1045+primOpTag (VecIndexScalarByteArrayOp WordVec 16 W16) = 1046+primOpTag (VecIndexScalarByteArrayOp WordVec 8 W32) = 1047+primOpTag (VecIndexScalarByteArrayOp WordVec 4 W64) = 1048+primOpTag (VecIndexScalarByteArrayOp WordVec 64 W8) = 1049+primOpTag (VecIndexScalarByteArrayOp WordVec 32 W16) = 1050+primOpTag (VecIndexScalarByteArrayOp WordVec 16 W32) = 1051+primOpTag (VecIndexScalarByteArrayOp WordVec 8 W64) = 1052+primOpTag (VecIndexScalarByteArrayOp FloatVec 4 W32) = 1053+primOpTag (VecIndexScalarByteArrayOp FloatVec 2 W64) = 1054+primOpTag (VecIndexScalarByteArrayOp FloatVec 8 W32) = 1055+primOpTag (VecIndexScalarByteArrayOp FloatVec 4 W64) = 1056+primOpTag (VecIndexScalarByteArrayOp FloatVec 16 W32) = 1057+primOpTag (VecIndexScalarByteArrayOp FloatVec 8 W64) = 1058+primOpTag (VecReadScalarByteArrayOp IntVec 16 W8) = 1059+primOpTag (VecReadScalarByteArrayOp IntVec 8 W16) = 1060+primOpTag (VecReadScalarByteArrayOp IntVec 4 W32) = 1061+primOpTag (VecReadScalarByteArrayOp IntVec 2 W64) = 1062+primOpTag (VecReadScalarByteArrayOp IntVec 32 W8) = 1063+primOpTag (VecReadScalarByteArrayOp IntVec 16 W16) = 1064+primOpTag (VecReadScalarByteArrayOp IntVec 8 W32) = 1065+primOpTag (VecReadScalarByteArrayOp IntVec 4 W64) = 1066+primOpTag (VecReadScalarByteArrayOp IntVec 64 W8) = 1067+primOpTag (VecReadScalarByteArrayOp IntVec 32 W16) = 1068+primOpTag (VecReadScalarByteArrayOp IntVec 16 W32) = 1069+primOpTag (VecReadScalarByteArrayOp IntVec 8 W64) = 1070+primOpTag (VecReadScalarByteArrayOp WordVec 16 W8) = 1071+primOpTag (VecReadScalarByteArrayOp WordVec 8 W16) = 1072+primOpTag (VecReadScalarByteArrayOp WordVec 4 W32) = 1073+primOpTag (VecReadScalarByteArrayOp WordVec 2 W64) = 1074+primOpTag (VecReadScalarByteArrayOp WordVec 32 W8) = 1075+primOpTag (VecReadScalarByteArrayOp WordVec 16 W16) = 1076+primOpTag (VecReadScalarByteArrayOp WordVec 8 W32) = 1077+primOpTag (VecReadScalarByteArrayOp WordVec 4 W64) = 1078+primOpTag (VecReadScalarByteArrayOp WordVec 64 W8) = 1079+primOpTag (VecReadScalarByteArrayOp WordVec 32 W16) = 1080+primOpTag (VecReadScalarByteArrayOp WordVec 16 W32) = 1081+primOpTag (VecReadScalarByteArrayOp WordVec 8 W64) = 1082+primOpTag (VecReadScalarByteArrayOp FloatVec 4 W32) = 1083+primOpTag (VecReadScalarByteArrayOp FloatVec 2 W64) = 1084+primOpTag (VecReadScalarByteArrayOp FloatVec 8 W32) = 1085+primOpTag (VecReadScalarByteArrayOp FloatVec 4 W64) = 1086+primOpTag (VecReadScalarByteArrayOp FloatVec 16 W32) = 1087+primOpTag (VecReadScalarByteArrayOp FloatVec 8 W64) = 1088+primOpTag (VecWriteScalarByteArrayOp IntVec 16 W8) = 1089+primOpTag (VecWriteScalarByteArrayOp IntVec 8 W16) = 1090+primOpTag (VecWriteScalarByteArrayOp IntVec 4 W32) = 1091+primOpTag (VecWriteScalarByteArrayOp IntVec 2 W64) = 1092+primOpTag (VecWriteScalarByteArrayOp IntVec 32 W8) = 1093+primOpTag (VecWriteScalarByteArrayOp IntVec 16 W16) = 1094+primOpTag (VecWriteScalarByteArrayOp IntVec 8 W32) = 1095+primOpTag (VecWriteScalarByteArrayOp IntVec 4 W64) = 1096+primOpTag (VecWriteScalarByteArrayOp IntVec 64 W8) = 1097+primOpTag (VecWriteScalarByteArrayOp IntVec 32 W16) = 1098+primOpTag (VecWriteScalarByteArrayOp IntVec 16 W32) = 1099+primOpTag (VecWriteScalarByteArrayOp IntVec 8 W64) = 1100+primOpTag (VecWriteScalarByteArrayOp WordVec 16 W8) = 1101+primOpTag (VecWriteScalarByteArrayOp WordVec 8 W16) = 1102+primOpTag (VecWriteScalarByteArrayOp WordVec 4 W32) = 1103+primOpTag (VecWriteScalarByteArrayOp WordVec 2 W64) = 1104+primOpTag (VecWriteScalarByteArrayOp WordVec 32 W8) = 1105+primOpTag (VecWriteScalarByteArrayOp WordVec 16 W16) = 1106+primOpTag (VecWriteScalarByteArrayOp WordVec 8 W32) = 1107+primOpTag (VecWriteScalarByteArrayOp WordVec 4 W64) = 1108+primOpTag (VecWriteScalarByteArrayOp WordVec 64 W8) = 1109+primOpTag (VecWriteScalarByteArrayOp WordVec 32 W16) = 1110+primOpTag (VecWriteScalarByteArrayOp WordVec 16 W32) = 1111+primOpTag (VecWriteScalarByteArrayOp WordVec 8 W64) = 1112+primOpTag (VecWriteScalarByteArrayOp FloatVec 4 W32) = 1113+primOpTag (VecWriteScalarByteArrayOp FloatVec 2 W64) = 1114+primOpTag (VecWriteScalarByteArrayOp FloatVec 8 W32) = 1115+primOpTag (VecWriteScalarByteArrayOp FloatVec 4 W64) = 1116+primOpTag (VecWriteScalarByteArrayOp FloatVec 16 W32) = 1117+primOpTag (VecWriteScalarByteArrayOp FloatVec 8 W64) = 1118+primOpTag (VecIndexScalarOffAddrOp IntVec 16 W8) = 1119+primOpTag (VecIndexScalarOffAddrOp IntVec 8 W16) = 1120+primOpTag (VecIndexScalarOffAddrOp IntVec 4 W32) = 1121+primOpTag (VecIndexScalarOffAddrOp IntVec 2 W64) = 1122+primOpTag (VecIndexScalarOffAddrOp IntVec 32 W8) = 1123+primOpTag (VecIndexScalarOffAddrOp IntVec 16 W16) = 1124+primOpTag (VecIndexScalarOffAddrOp IntVec 8 W32) = 1125+primOpTag (VecIndexScalarOffAddrOp IntVec 4 W64) = 1126+primOpTag (VecIndexScalarOffAddrOp IntVec 64 W8) = 1127+primOpTag (VecIndexScalarOffAddrOp IntVec 32 W16) = 1128+primOpTag (VecIndexScalarOffAddrOp IntVec 16 W32) = 1129+primOpTag (VecIndexScalarOffAddrOp IntVec 8 W64) = 1130+primOpTag (VecIndexScalarOffAddrOp WordVec 16 W8) = 1131+primOpTag (VecIndexScalarOffAddrOp WordVec 8 W16) = 1132+primOpTag (VecIndexScalarOffAddrOp WordVec 4 W32) = 1133+primOpTag (VecIndexScalarOffAddrOp WordVec 2 W64) = 1134+primOpTag (VecIndexScalarOffAddrOp WordVec 32 W8) = 1135+primOpTag (VecIndexScalarOffAddrOp WordVec 16 W16) = 1136+primOpTag (VecIndexScalarOffAddrOp WordVec 8 W32) = 1137+primOpTag (VecIndexScalarOffAddrOp WordVec 4 W64) = 1138+primOpTag (VecIndexScalarOffAddrOp WordVec 64 W8) = 1139+primOpTag (VecIndexScalarOffAddrOp WordVec 32 W16) = 1140+primOpTag (VecIndexScalarOffAddrOp WordVec 16 W32) = 1141+primOpTag (VecIndexScalarOffAddrOp WordVec 8 W64) = 1142+primOpTag (VecIndexScalarOffAddrOp FloatVec 4 W32) = 1143+primOpTag (VecIndexScalarOffAddrOp FloatVec 2 W64) = 1144+primOpTag (VecIndexScalarOffAddrOp FloatVec 8 W32) = 1145+primOpTag (VecIndexScalarOffAddrOp FloatVec 4 W64) = 1146+primOpTag (VecIndexScalarOffAddrOp FloatVec 16 W32) = 1147+primOpTag (VecIndexScalarOffAddrOp FloatVec 8 W64) = 1148+primOpTag (VecReadScalarOffAddrOp IntVec 16 W8) = 1149+primOpTag (VecReadScalarOffAddrOp IntVec 8 W16) = 1150+primOpTag (VecReadScalarOffAddrOp IntVec 4 W32) = 1151+primOpTag (VecReadScalarOffAddrOp IntVec 2 W64) = 1152+primOpTag (VecReadScalarOffAddrOp IntVec 32 W8) = 1153+primOpTag (VecReadScalarOffAddrOp IntVec 16 W16) = 1154+primOpTag (VecReadScalarOffAddrOp IntVec 8 W32) = 1155+primOpTag (VecReadScalarOffAddrOp IntVec 4 W64) = 1156+primOpTag (VecReadScalarOffAddrOp IntVec 64 W8) = 1157+primOpTag (VecReadScalarOffAddrOp IntVec 32 W16) = 1158+primOpTag (VecReadScalarOffAddrOp IntVec 16 W32) = 1159+primOpTag (VecReadScalarOffAddrOp IntVec 8 W64) = 1160+primOpTag (VecReadScalarOffAddrOp WordVec 16 W8) = 1161+primOpTag (VecReadScalarOffAddrOp WordVec 8 W16) = 1162+primOpTag (VecReadScalarOffAddrOp WordVec 4 W32) = 1163+primOpTag (VecReadScalarOffAddrOp WordVec 2 W64) = 1164+primOpTag (VecReadScalarOffAddrOp WordVec 32 W8) = 1165+primOpTag (VecReadScalarOffAddrOp WordVec 16 W16) = 1166+primOpTag (VecReadScalarOffAddrOp WordVec 8 W32) = 1167+primOpTag (VecReadScalarOffAddrOp WordVec 4 W64) = 1168+primOpTag (VecReadScalarOffAddrOp WordVec 64 W8) = 1169+primOpTag (VecReadScalarOffAddrOp WordVec 32 W16) = 1170+primOpTag (VecReadScalarOffAddrOp WordVec 16 W32) = 1171+primOpTag (VecReadScalarOffAddrOp WordVec 8 W64) = 1172+primOpTag (VecReadScalarOffAddrOp FloatVec 4 W32) = 1173+primOpTag (VecReadScalarOffAddrOp FloatVec 2 W64) = 1174+primOpTag (VecReadScalarOffAddrOp FloatVec 8 W32) = 1175+primOpTag (VecReadScalarOffAddrOp FloatVec 4 W64) = 1176+primOpTag (VecReadScalarOffAddrOp FloatVec 16 W32) = 1177+primOpTag (VecReadScalarOffAddrOp FloatVec 8 W64) = 1178+primOpTag (VecWriteScalarOffAddrOp IntVec 16 W8) = 1179+primOpTag (VecWriteScalarOffAddrOp IntVec 8 W16) = 1180+primOpTag (VecWriteScalarOffAddrOp IntVec 4 W32) = 1181+primOpTag (VecWriteScalarOffAddrOp IntVec 2 W64) = 1182+primOpTag (VecWriteScalarOffAddrOp IntVec 32 W8) = 1183+primOpTag (VecWriteScalarOffAddrOp IntVec 16 W16) = 1184+primOpTag (VecWriteScalarOffAddrOp IntVec 8 W32) = 1185+primOpTag (VecWriteScalarOffAddrOp IntVec 4 W64) = 1186+primOpTag (VecWriteScalarOffAddrOp IntVec 64 W8) = 1187+primOpTag (VecWriteScalarOffAddrOp IntVec 32 W16) = 1188+primOpTag (VecWriteScalarOffAddrOp IntVec 16 W32) = 1189+primOpTag (VecWriteScalarOffAddrOp IntVec 8 W64) = 1190+primOpTag (VecWriteScalarOffAddrOp WordVec 16 W8) = 1191+primOpTag (VecWriteScalarOffAddrOp WordVec 8 W16) = 1192+primOpTag (VecWriteScalarOffAddrOp WordVec 4 W32) = 1193+primOpTag (VecWriteScalarOffAddrOp WordVec 2 W64) = 1194+primOpTag (VecWriteScalarOffAddrOp WordVec 32 W8) = 1195+primOpTag (VecWriteScalarOffAddrOp WordVec 16 W16) = 1196+primOpTag (VecWriteScalarOffAddrOp WordVec 8 W32) = 1197+primOpTag (VecWriteScalarOffAddrOp WordVec 4 W64) = 1198+primOpTag (VecWriteScalarOffAddrOp WordVec 64 W8) = 1199+primOpTag (VecWriteScalarOffAddrOp WordVec 32 W16) = 1200+primOpTag (VecWriteScalarOffAddrOp WordVec 16 W32) = 1201+primOpTag (VecWriteScalarOffAddrOp WordVec 8 W64) = 1202+primOpTag (VecWriteScalarOffAddrOp FloatVec 4 W32) = 1203+primOpTag (VecWriteScalarOffAddrOp FloatVec 2 W64) = 1204+primOpTag (VecWriteScalarOffAddrOp FloatVec 8 W32) = 1205+primOpTag (VecWriteScalarOffAddrOp FloatVec 4 W64) = 1206+primOpTag (VecWriteScalarOffAddrOp FloatVec 16 W32) = 1207+primOpTag (VecWriteScalarOffAddrOp FloatVec 8 W64) = 1208+primOpTag PrefetchByteArrayOp3 = 1209+primOpTag PrefetchMutableByteArrayOp3 = 1210+primOpTag PrefetchAddrOp3 = 1211+primOpTag PrefetchValueOp3 = 1212+primOpTag PrefetchByteArrayOp2 = 1213+primOpTag PrefetchMutableByteArrayOp2 = 1214+primOpTag PrefetchAddrOp2 = 1215+primOpTag PrefetchValueOp2 = 1216+primOpTag PrefetchByteArrayOp1 = 1217+primOpTag PrefetchMutableByteArrayOp1 = 1218+primOpTag PrefetchAddrOp1 = 1219+primOpTag PrefetchValueOp1 = 1220+primOpTag PrefetchByteArrayOp0 = 1221+primOpTag PrefetchMutableByteArrayOp0 = 1222+primOpTag PrefetchAddrOp0 = 1223+primOpTag PrefetchValueOp0 = 1224
ghc-lib/stage0/lib/ghcversion.h view
@@ -5,11 +5,11 @@ #define __GLASGOW_HASKELL__ 901 #endif #if !defined(__GLASGOW_HASKELL_FULL_VERSION__)-#define __GLASGOW_HASKELL_FULL_VERSION__ "9.1.0.20201101"+#define __GLASGOW_HASKELL_FULL_VERSION__ "9.1.0.20201201" #endif #define __GLASGOW_HASKELL_PATCHLEVEL1__ 0-#define __GLASGOW_HASKELL_PATCHLEVEL2__ 20201101+#define __GLASGOW_HASKELL_PATCHLEVEL2__ 20201201 #define MIN_VERSION_GLASGOW_HASKELL(ma,mi,pl1,pl2) (\ ((ma)*100+(mi)) < __GLASGOW_HASKELL__ || \
ghc-lib/stage0/lib/llvm-targets view
@@ -1,7 +1,7 @@-[("i386-unknown-windows", ("e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32", "pentium4", ""))-,("i686-unknown-windows", ("e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32", "pentium4", ""))-,("x86_64-unknown-windows", ("e-m:w-i64:64-f80:128-n8:16:32:64-S128", "x86-64", ""))-,("arm-unknown-linux-gnueabi", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "arm7tdmi", "+soft-float -fp16 -vfp2 -vfp2sp -vfp2d16 -vfp2d16sp -vfp3 -vfp3sp -vfp3d16 -vfp3d16sp -vfp4 -vfp4sp -vfp4d16 -vfp4d16sp -fp-armv8 -fp-armv8sp -fp-armv8d16 -fp-armv8d16sp -fullfp16 -neon -crypto -dotprod -fp16fml -fp64 -d32 -fpregs +strict-align"))+[("i386-unknown-windows", ("e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:32-n8:16:32-a:0:32-S32", "pentium4", ""))+,("i686-unknown-windows", ("e-m:x-p:32:32-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:32-n8:16:32-a:0:32-S32", "pentium4", ""))+,("x86_64-unknown-windows", ("e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", "x86-64", ""))+,("arm-unknown-linux-gnueabi", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "arm7tdmi", "+strict-align")) ,("arm-unknown-linux-gnueabihf", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "arm1176jzf-s", "+strict-align")) ,("arm-unknown-linux-musleabihf", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "arm1176jzf-s", "+strict-align")) ,("armv6-unknown-linux-gnueabihf", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "arm1136jf-s", "+strict-align"))@@ -21,31 +21,32 @@ ,("aarch64-unknown-linux-gnu", ("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", "generic", "+neon")) ,("aarch64-unknown-linux-musl", ("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", "generic", "+neon")) ,("aarch64-unknown-linux", ("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", "generic", "+neon"))-,("i386-unknown-linux-gnu", ("e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128", "pentium4", ""))-,("i386-unknown-linux-musl", ("e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128", "pentium4", ""))-,("i386-unknown-linux", ("e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128", "pentium4", ""))-,("i686-unknown-linux-gnu", ("e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128", "pentium4", ""))-,("i686-unknown-linux-musl", ("e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128", "pentium4", ""))-,("i686-unknown-linux", ("e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128", "pentium4", ""))-,("x86_64-unknown-linux-gnu", ("e-m:e-i64:64-f80:128-n8:16:32:64-S128", "x86-64", ""))-,("x86_64-unknown-linux-musl", ("e-m:e-i64:64-f80:128-n8:16:32:64-S128", "x86-64", ""))-,("x86_64-unknown-linux", ("e-m:e-i64:64-f80:128-n8:16:32:64-S128", "x86-64", ""))-,("x86_64-unknown-linux-android", ("e-m:e-i64:64-f80:128-n8:16:32:64-S128", "x86-64", "+sse4.2 +popcnt +cx16"))-,("armv7-unknown-linux-androideabi", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "generic", "+fpregs +vfp2 +vfp2d16 +vfp2d16sp +vfp2sp +vfp3 +vfp3d16 +vfp3d16sp +vfp3sp -fp16 -vfp4 -vfp4d16 -vfp4d16sp -vfp4sp -fp-armv8 -fp-armv8d16 -fp-armv8d16sp -fp-armv8sp -fullfp16 +fp64 +d32 +neon -crypto -fp16fml"))+,("i386-unknown-linux-gnu", ("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128", "pentium4", ""))+,("i386-unknown-linux-musl", ("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128", "pentium4", ""))+,("i386-unknown-linux", ("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128", "pentium4", ""))+,("i686-unknown-linux-gnu", ("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128", "pentium4", ""))+,("i686-unknown-linux-musl", ("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128", "pentium4", ""))+,("i686-unknown-linux", ("e-m:e-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:32-n8:16:32-S128", "pentium4", ""))+,("x86_64-unknown-linux-gnu", ("e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", "x86-64", ""))+,("x86_64-unknown-linux-musl", ("e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", "x86-64", ""))+,("x86_64-unknown-linux", ("e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", "x86-64", ""))+,("x86_64-unknown-linux-android", ("e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", "x86-64", "+sse4.2 +popcnt +cx16"))+,("armv7-unknown-linux-androideabi", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "generic", "+fpregs +vfp2 +vfp2sp +vfp3 +vfp3d16 +vfp3d16sp +vfp3sp -fp16 -vfp4 -vfp4d16 -vfp4d16sp -vfp4sp -fp-armv8 -fp-armv8d16 -fp-armv8d16sp -fp-armv8sp -fullfp16 +fp64 +d32 +neon -crypto -fp16fml")) ,("aarch64-unknown-linux-android", ("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", "generic", "+neon"))-,("armv7a-unknown-linux-androideabi", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "generic", "+fpregs +vfp2 +vfp2d16 +vfp2d16sp +vfp2sp +vfp3 +vfp3d16 +vfp3d16sp +vfp3sp -fp16 -vfp4 -vfp4d16 -vfp4d16sp -vfp4sp -fp-armv8 -fp-armv8d16 -fp-armv8d16sp -fp-armv8sp -fullfp16 +fp64 +d32 +neon -crypto -fp16fml"))+,("armv7a-unknown-linux-androideabi", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "generic", "+fpregs +vfp2 +vfp2sp +vfp3 +vfp3d16 +vfp3d16sp +vfp3sp -fp16 -vfp4 -vfp4d16 -vfp4d16sp -vfp4sp -fp-armv8 -fp-armv8d16 -fp-armv8d16sp -fp-armv8sp -fullfp16 +fp64 +d32 +neon -crypto -fp16fml")) ,("powerpc64le-unknown-linux-gnu", ("e-m:e-i64:64-n32:64", "ppc64le", "")) ,("powerpc64le-unknown-linux-musl", ("e-m:e-i64:64-n32:64", "ppc64le", "+secure-plt")) ,("powerpc64le-unknown-linux", ("e-m:e-i64:64-n32:64", "ppc64le", "")) ,("s390x-ibm-linux", ("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-a:8:16-n32:64", "z10", ""))-,("i386-apple-darwin", ("e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128", "yonah", ""))-,("x86_64-apple-darwin", ("e-m:o-i64:64-f80:128-n8:16:32:64-S128", "core2", ""))-,("armv7-apple-ios", ("e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32", "generic", ""))-,("aarch64-apple-ios", ("e-m:o-i64:64-i128:128-n32:64-S128", "generic", "+neon"))-,("i386-apple-ios", ("e-m:o-p:32:32-f64:32:64-f80:128-n8:16:32-S128", "yonah", ""))-,("x86_64-apple-ios", ("e-m:o-i64:64-f80:128-n8:16:32:64-S128", "core2", ""))-,("amd64-portbld-freebsd", ("e-m:e-i64:64-f80:128-n8:16:32:64-S128", "x86-64", ""))-,("x86_64-unknown-freebsd", ("e-m:e-i64:64-f80:128-n8:16:32:64-S128", "x86-64", ""))+,("i386-apple-darwin", ("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:128-n8:16:32-S128", "penryn", ""))+,("x86_64-apple-darwin", ("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", "penryn", ""))+,("arm64-apple-darwin", ("e-m:o-i64:64-i128:128-n32:64-S128", "vortex", "+v8.3a +fp-armv8 +neon +crc +crypto +fullfp16 +ras +lse +rdm +rcpc +zcm +zcz +sha2 +aes"))+,("armv7-apple-ios", ("e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32", "generic", ""))+,("aarch64-apple-ios", ("e-m:o-i64:64-i128:128-n32:64-S128", "apple-a7", "+fp-armv8 +neon +crypto +zcm +zcz +sha2 +aes"))+,("i386-apple-ios", ("e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-f64:32:64-f80:128-n8:16:32-S128", "yonah", ""))+,("x86_64-apple-ios", ("e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", "core2", ""))+,("amd64-portbld-freebsd", ("e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", "x86-64", ""))+,("x86_64-unknown-freebsd", ("e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", "x86-64", "")) ,("aarch64-unknown-freebsd", ("e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128", "generic", "+neon")) ,("armv6-unknown-freebsd-gnueabihf", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "arm1176jzf-s", "+strict-align")) ,("armv7-unknown-freebsd-gnueabihf", ("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", "generic", "+strict-align"))
includes/CodeGen.Platform.hs view
@@ -94,7 +94,7 @@ # define zmm14 30 # define zmm15 31 --- Note: these are only needed for ARM/ARM64 because globalRegMaybe is now used in CmmSink.hs.+-- Note: these are only needed for ARM/AArch64 because globalRegMaybe is now used in CmmSink.hs. -- Since it's only used to check 'isJust', the actual values don't matter, thus -- I'm not sure if these are the correct numberings. -- Normally, the register names are just stringified as part of the REG() macro@@ -1096,4 +1096,3 @@ freeReg = panic "freeReg not defined for this platform" #endif-
libraries/ghci/GHCi/InfoTable.hsc view
@@ -69,7 +69,7 @@ | ArchX86_64 | ArchAlpha | ArchARM- | ArchARM64+ | ArchAArch64 | ArchPPC64 | ArchPPC64LE | ArchS390X@@ -102,7 +102,7 @@ #elif defined(arm_HOST_ARCH) Just ArchARM #elif defined(aarch64_HOST_ARCH)- Just ArchARM64+ Just ArchAArch64 #elif defined(powerpc64_HOST_ARCH) Just ArchPPC64 #elif defined(powerpc64le_HOST_ARCH)@@ -214,7 +214,7 @@ , 0x11, 0xff, 0x2f, 0xe1 , byte0 w32, byte1 w32, byte2 w32, byte3 w32] - ArchARM64 { } ->+ ArchAArch64 { } -> -- Generates: -- -- ldr x1, label
libraries/ghci/GHCi/Run.hs view
@@ -32,7 +32,7 @@ import Data.ByteString (ByteString) import qualified Data.ByteString.Unsafe as B import GHC.Exts-import GHC.Exts.Heap+import qualified GHC.Exts.Heap as Heap import GHC.Stack import Foreign hiding (void) import Foreign.C@@ -93,8 +93,8 @@ toRemotePtr <$> mkConInfoTable tc ptrs nptrs tag ptrtag desc StartTH -> startTH GetClosure ref -> do- clos <- getClosureData =<< localRef ref- mapM (\(Box x) -> mkRemoteRef (HValue x)) clos+ clos <- Heap.getClosureData =<< localRef ref+ mapM (\(Heap.Box x) -> mkRemoteRef (HValue x)) clos Seq ref -> doSeq ref ResumeSeq ref -> resumeSeq ref _other -> error "GHCi.Run.run"