[Git][ghc/ghc][wip/jeltsch/textual-bytecode-output] Add support for textual output of bytecode file content
by Wolfgang Jeltsch (@jeltsch) 21 Jul '26
by Wolfgang Jeltsch (@jeltsch) 21 Jul '26
21 Jul '26
Wolfgang Jeltsch pushed to branch wip/jeltsch/textual-bytecode-output at Glasgow Haskell Compiler / GHC
Commits:
1758ebba by Wolfgang Jeltsch at 2026-07-21T17:23:43+03:00
Add support for textual output of bytecode file content
This resolves #26909.
- - - - -
13 changed files:
- + changelog.d/show-byte-code
- compiler/GHC/ByteCode/Serialize.hs
- + compiler/GHC/ByteCode/Show.hs
- compiler/ghc.cabal.in
- docs/users_guide/using.rst
- ghc/GHC/Driver/Session/Mode.hs
- ghc/Main.hs
- + testsuite/tests/show-bytecode/Example.hs
- + testsuite/tests/show-bytecode/Makefile
- + testsuite/tests/show-bytecode/all.T
- + testsuite/tests/show-bytecode/show-bytecode-breakpoints.stdout
- + testsuite/tests/show-bytecode/show-bytecode-hpc.stdout
- + testsuite/tests/show-bytecode/show-bytecode-vanilla.stdout
Changes:
=====================================
changelog.d/show-byte-code
=====================================
@@ -0,0 +1,8 @@
+section: bytecode
+synopsis: Add support for textual output of bytecode file content
+issues: #26909
+mrs: !16386
+description: {
+ There is now an option `--show-byte-code` for outputting relevant
+ content of a bytecode file in textual form.
+}
=====================================
compiler/GHC/ByteCode/Serialize.hs
=====================================
@@ -6,7 +6,7 @@
{- | This module implements the serialization of bytecode objects to and from disk.
-}
module GHC.ByteCode.Serialize
- ( writeBinByteCode, readBinByteCode
+ ( writeBinByteCode, readBinByteCode, readOnDiskModuleByteCode
, ModuleByteCode(..)
, BytecodeLibX(..)
, BytecodeLib
=====================================
compiler/GHC/ByteCode/Show.hs
=====================================
@@ -0,0 +1,531 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE RecordWildCards #-}
+
+-- | This module implements the output of textual information about the contents
+-- of bytecode files. It is the backbone of the @--show-byte-code@ option.
+module GHC.ByteCode.Show (showByteCode) where
+
+import Prelude ((+), (-), Integral, div)
+import Control.Arrow ((>>>))
+import Control.Exception (assert)
+import Data.Eq ((==))
+import Data.Ord ((>=))
+import Data.Bits (FiniteBits, finiteBitSize)
+import Data.Function (($), id, (.))
+import Data.Tuple (fst, uncurry)
+import Data.Bool (Bool, otherwise, not)
+import Data.Int (Int)
+import Data.Word (Word)
+import Data.Maybe (Maybe, maybe)
+import Data.Either (Either, either)
+import Data.List (length, (++), map, zipWith4, take, drop, replicate)
+import Data.String (String)
+import Data.ByteString (ByteString)
+import Data.ByteString.Short (ShortByteString)
+import Data.IntMap (IntMap)
+import Data.IntMap qualified as IntMap (toList)
+import Data.Array (bounds, indices, elems)
+import Numeric (showHex)
+import Text.Show (show)
+import System.IO (IO, FilePath)
+import GHC.Data.Strict qualified as Strict (Maybe, maybe)
+import GHC.Data.FastString (unpackFS)
+import GHC.Data.FlatBag (FlatBag, elemsFlatBag)
+import GHC.Fingerprint (Fingerprint)
+import GHC.Types.SrcLoc (noSrcSpan)
+import GHC.Types.Name (Name)
+import GHC.Types.Name.Occurrence (OccName)
+import GHC.Types.Tickish (BreakTickIndex, BreakpointId (..))
+import GHC.Types.SptEntry (SptEntry (..))
+import GHC.Types.Error (MessageClass (MCDump))
+import GHC.Utils.Logger (Logger, logMsg)
+import GHC.Utils.Binary (BinSrcSpan (..))
+import GHC.Utils.Encoding.UTF8 (utf8DecodeShortByteString, utf8DecodeByteString)
+import GHC.Utils.Outputable
+ (
+ defaultDumpStyle,
+ SDoc,
+ text,
+ (<>),
+ (<+>),
+ quotes,
+ hsep,
+ vcat,
+ hang,
+ withPprStyle,
+ ppr
+ )
+import GHC.Unit.Types (Module)
+import GHC.Iface.Type (IfaceType, IfaceTvBndr, IfaceIdBndr)
+import GHC.HsToCore.Breakpoints (ModBreaks (..))
+import GHC.ByteCode.Types
+ (
+ FFIInfo (..),
+ BCONPtr (..),
+ BCOPtr (..),
+ UnlinkedBCO (..),
+ ByteCodeHpcInfo (..),
+ CompiledByteCode (..)
+ )
+import GHC.ByteCode.Breakpoints
+ (
+ InternalBreakpointId (..),
+ InternalBreakLoc (..),
+ CgBreakInfo (..),
+ InternalModBreaks (..)
+ )
+import GHC.ByteCode.Binary (OnDiskModuleByteCode (..))
+import GHC.ByteCode.Serialize (readOnDiskModuleByteCode)
+import GHC.Driver.Env.Types (HscEnv)
+import GHCi.FFI (FFIType)
+import GHCi.Message (ConInfoTable (..))
+
+-- | Outputs textual information about the contents of a bytecode file.
+showByteCode :: Logger -> HscEnv -> FilePath -> IO ()
+showByteCode logger env path = do
+ byteCode <- readOnDiskModuleByteCode env path
+ logMsg logger
+ MCDump
+ noSrcSpan
+ (withPprStyle defaultDumpStyle $ pprOnDiskModuleByteCode byteCode)
+
+-- | Constructs textual information about the contents of a bytecode file.
+pprOnDiskModuleByteCode :: OnDiskModuleByteCode -> SDoc
+pprOnDiskModuleByteCode OnDiskModuleByteCode {..}
+ = vcat [
+ pprModuleIdent $ odgbc_module,
+ pprOnDiskModuleByteCodeHash $ odgbc_hash,
+ pprCompiledByteCode odgbc_module $ odgbc_compiled_byte_code
+ ]
+
+-- | Constructs textual information about the name of a module.
+pprModuleIdent :: Module -> SDoc
+pprModuleIdent = entry (text "name") . ppr
+
+-- | Constructs textual information about the hash of a module.
+pprOnDiskModuleByteCodeHash :: Fingerprint -> SDoc
+pprOnDiskModuleByteCodeHash = entry (text "hash") . ppr
+
+-- | Constructs textual information about bytecode.
+pprCompiledByteCode :: Module -- ^ The enclosing module
+ -> CompiledByteCode -- ^ The bytecode
+ -> SDoc -- ^ The textual information
+pprCompiledByteCode currentModule CompiledByteCode {..}
+ = vcat [
+ pprByteCodeObjects currentModule $ bc_bcos,
+ pprDataConstructorInfoTables $ bc_itbls,
+ pprTopLevelStrings $ bc_strs,
+ pprBreakpoints currentModule $ bc_breaks,
+ pprStaticPointerTableEntries $ bc_spt_entries,
+ pprHPCInfo $ bc_hpc_info
+ ]
+
+-- | Constructs textual information about bytecode objects.
+pprByteCodeObjects :: Module -- ^ The enlosing module
+ -> FlatBag UnlinkedBCO -- ^ The bytecode objects
+ -> SDoc -- ^ The textual information
+pprByteCodeObjects currentModule = entry (text "objects") .
+ vcatOrNone .
+ map (pprByteCodeObject currentModule) .
+ elemsFlatBag
+
+-- | Constructs textual information about a single bytecode object.
+pprByteCodeObject :: Module -- ^ The enclosing module
+ -> UnlinkedBCO -- ^ The bytecode object
+ -> SDoc -- ^ The textual information
+pprByteCodeObject currentModule byteCodeObject = case byteCodeObject of
+ UnlinkedBCO {..}
+ -> entry (text "ordinary object" <+> quotes (ppr unlinkedBCOName)) $
+ vcat [
+ pprArity $ unlinkedBCOArity,
+ pprLiterals currentModule $ unlinkedBCOLits,
+ pprPointers currentModule $ unlinkedBCOPtrs
+ ]
+ UnlinkedStaticCon {..}
+ -> entry (
+ text "static-construction object" <+>
+ quotes (ppr unlinkedStaticConName)
+ )
+ $
+ vcat [
+ pprDataConstructorName $ unlinkedStaticConDataConName,
+ pprLiftedness $ not unlinkedStaticConIsUnlifted,
+ pprLiterals currentModule $ unlinkedStaticConLits,
+ pprPointers currentModule $ unlinkedStaticConPtrs
+ ]
+
+-- | Constructs textual information about the arity of an ordinary bytecode
+-- object.
+pprArity :: Int -> SDoc
+pprArity = entry (text "arity") . ppr
+
+-- | Constructs textual information about the data constructor name of a
+-- static-construction bytecode object.
+pprDataConstructorName :: Name -> SDoc
+pprDataConstructorName = entry (text "data constructor name") . ppr
+
+-- | Constructs textual information about the liftedness of a
+-- static-construction bytecode object.
+pprLiftedness :: Bool -> SDoc
+pprLiftedness = entry (text "lifted") . noOrYes
+
+-- | Constructs textual information about literals.
+pprLiterals :: Module -- ^ The enclosing module
+ -> FlatBag BCONPtr -- ^ The literals
+ -> SDoc -- ^ The textual information
+pprLiterals currentModule = entry (text "literals") .
+ vcatOrNone .
+ map (pprLiteral currentModule) .
+ elemsFlatBag
+
+-- | Constructs textual information about a single literal.
+pprLiteral :: Module -- ^ The enclosing module
+ -> BCONPtr -- ^ The literal
+ -> SDoc -- ^ The textual information
+pprLiteral currentModule literal = case literal of
+ BCONPtrWord word
+ -> text "word" <+>
+ ppr word
+ BCONPtrLbl label
+ -> text "label" <+>
+ quotes (ppr label)
+ BCONPtrItbl infoTableName
+ -> text "info table of" <+>
+ quotes (ppr infoTableName)
+ BCONPtrAddr addrName
+ -> text "address" <+>
+ quotes (ppr addrName)
+ BCONPtrStr encodedString
+ -> text "top-level string" <+>
+ text (show (utf8DecodeByteString encodedString))
+ BCONPtrFS string
+ -> text "top-level string" <+>
+ text (show (unpackFS string))
+ BCONPtrFFIInfo ffiInfo
+ -> text "foreign function" <+>
+ quotes (pprFFIInfo ffiInfo)
+ BCONPtrCostCentre breakpointID
+ -> text "cost center of breakpoint" <+>
+ pprInternalBreakpointID currentModule breakpointID
+
+-- | Constructs textual information about FFI info.
+pprFFIInfo :: FFIInfo -> SDoc
+pprFFIInfo FFIInfo {..}
+ = hsep (map (pprFFIType >>> (<+> text "->")) ffiInfoArgs) <+>
+ pprFFIType ffiInfoRet
+
+-- | Constructs textual information about an FFI type.
+pprFFIType :: FFIType -> SDoc
+pprFFIType ffiType = assert (take 3 ident == "FFI") $ text (drop 3 ident) where
+
+ ident :: String
+ ident = show ffiType
+
+-- | Constructs textual information about the ID of a bytecode breakpoint.
+pprInternalBreakpointID
+ :: Module -- ^ The enclosing module
+ -> InternalBreakpointId -- ^ The ID of the bytecode breakpoint
+ -> SDoc -- ^ The textual information
+pprInternalBreakpointID currentModule InternalBreakpointId {..}
+ | ibi_info_mod == currentModule = indexDoc
+ | otherwise = indexDoc <+>
+ text "in" <+>
+ ppr ibi_info_mod
+ where
+
+ indexDoc :: SDoc
+ indexDoc = ppr ibi_info_index
+
+-- | Constructs textual information about pointers.
+pprPointers :: Module -- ^ The enclosing module
+ -> FlatBag BCOPtr -- ^ The pointers
+ -> SDoc -- ^ The textual information
+pprPointers currentModule = entry (text "utilized items") .
+ vcatOrNone .
+ map (pprPointer currentModule) .
+ elemsFlatBag
+
+-- | Constructs textual information about a single pointer.
+pprPointer :: Module -- ^ The enclosing module
+ -> BCOPtr -- ^ The pointer
+ -> SDoc -- ^ The textual information
+pprPointer currentModule pointer = case pointer of
+ BCOPtrName name
+ -> text "item named" <+> quotes (ppr name)
+ BCOPtrPrimOp primOp
+ -> text "primitive operation" <+> quotes (ppr primOp)
+ BCOPtrBCO byteCodeObject
+ -> pprByteCodeObject currentModule byteCodeObject
+ BCOPtrBreakArray breakArrayModule
+ -> text "break array of module" <+> quotes (ppr breakArrayModule)
+
+-- | Constructs textual information about data constructor info tables.
+pprDataConstructorInfoTables :: [(Name, ConInfoTable)] -> SDoc
+pprDataConstructorInfoTables = entry (text "data constructor info tables") .
+ vcatOrNone .
+ map (uncurry pprDataConstructorInfoTable)
+
+-- | Constructs textual information about a single data constructor info table.
+pprDataConstructorInfoTable :: Name -> ConInfoTable -> SDoc
+pprDataConstructorInfoTable dataConstrName ConInfoTable {..}
+ = entry (text "info table of" <+> quotes (ppr dataConstrName)) $
+ vcat [
+ pprPointerWordCount $ conItblPtrs,
+ pprNonPointerWordCount $ conItblNPtrs
+ ]
+
+-- | Constructs textual information about a number of pointer words.
+pprPointerWordCount :: Int -> SDoc
+pprPointerWordCount = entry (text "number of words for pointers") . ppr
+
+-- | Constructs textual information about a number of non-pointer words.
+pprNonPointerWordCount :: Int -> SDoc
+pprNonPointerWordCount = entry (text "number of words for non-pointers") . ppr
+
+-- | Constructs textual information about top-level strings.
+pprTopLevelStrings :: [(Name, ByteString)] -> SDoc
+pprTopLevelStrings = entry (text "top-level strings") .
+ vcatOrNone .
+ map (uncurry pprTopLevelString)
+
+-- | Constructs textual information about a single top-level string.
+pprTopLevelString :: Name -> ByteString -> SDoc
+pprTopLevelString stringName encodedString = entry (ppr stringName) $
+ text $
+ show $
+ utf8DecodeByteString $
+ encodedString
+
+-- | Constructs textual information about breakpoints.
+pprBreakpoints :: Module -- ^ The enclosing module
+ -> Maybe InternalModBreaks -- ^ The breakpoints
+ -> SDoc -- ^ The textual information
+pprBreakpoints currentModule
+ = entry (text "breakpoints") .
+ maybe (text "<none>") (pprActualBreakpoints currentModule)
+
+-- | Constructs textual information about actual breakpoints.
+pprActualBreakpoints :: Module -- ^ The enclosing module
+ -> InternalModBreaks -- ^ The actual breakpoints
+ -> SDoc -- ^ The textual information
+pprActualBreakpoints currentModule InternalModBreaks {..}
+ = vcat [
+ pprSourceBreakpoints currentModule $ imodBreaks_modBreaks,
+ pprByteCodeBreakpoints currentModule $ imodBreaks_breakInfo
+ ]
+
+-- | Constructs textual information about source breakpoints.
+pprSourceBreakpoints :: Module -- ^ The enclosing module
+ -> ModBreaks -- ^ The source breakpoints
+ -> SDoc -- ^ The textual information
+pprSourceBreakpoints currentModule ModBreaks {..}
+ = entry (text "source breakpoints") $
+ assert (modBreaks_module == currentModule) $
+ assert (bounds modBreaks_locs_ == bounds modBreaks_decls) $
+ assert (bounds modBreaks_locs_ == bounds modBreaks_vars) $
+ vcatOrNone $
+ zipWith4 pprSourceBreakpoint (indices modBreaks_locs_)
+ (elems modBreaks_locs_)
+ (elems modBreaks_decls)
+ (elems modBreaks_vars)
+ -- The cost center infos in 'modBreaks_ccs', when present, just contain
+ -- textual representations of the declaration paths in 'modBreaks_decls'
+ -- and the source spans in 'modBreaks_locs_' and are therefore never
+ -- shown.
+
+-- | Constructs textual information about a single source breakpoint.
+pprSourceBreakpoint :: BreakTickIndex
+ -> BinSrcSpan
+ -> [String]
+ -> [OccName]
+ -> SDoc
+pprSourceBreakpoint ix srcSpan declarationPath freeVars
+ = entry (text "source breakpoint" <+> ppr ix) $
+ vcat [
+ pprSrcSpan $ srcSpan,
+ pprDeclarationPath $ declarationPath,
+ pprFreeVariables $ freeVars
+ ]
+
+-- | Constructs textual information about a source span.
+pprSrcSpan :: BinSrcSpan -> SDoc
+pprSrcSpan = entry (text "source span") . ppr . unBinSrcSpan
+
+-- | Constructs textual information about a declaration path.
+pprDeclarationPath :: [String] -> SDoc
+pprDeclarationPath = entry (text "declaration path") . vcatOrEmpty . map text
+
+-- | Constructs textual information about free variables.
+pprFreeVariables :: [OccName] -> SDoc
+pprFreeVariables = entry (text "free variables") . vcatOrNone . map ppr
+
+-- | Constructs textual information about bytecode breakpoints.
+pprByteCodeBreakpoints :: Module -- ^ The enclosing module
+ -> IntMap CgBreakInfo -- ^ The bytecode breakpoints
+ -> SDoc -- ^ The textual information
+pprByteCodeBreakpoints currentModule
+ = entry (text "bytecode breakpoints") .
+ vcatOrNone .
+ map (uncurry (pprByteCodeBreakpoint currentModule)) .
+ IntMap.toList
+
+-- | Constructs textual information about a single bytecode breakpoint.
+pprByteCodeBreakpoint :: Module -- ^ The enclosing module
+ -> Int -- ^ The index of the bytecode breakpoint
+ -> CgBreakInfo -- ^ The bytecode breakpoint
+ -> SDoc -- ^ The textual information
+pprByteCodeBreakpoint currentModule ix CgBreakInfo {..}
+ = entry (text "bytecode breakpoint" <+> ppr ix) $
+ vcat [
+ pprType $ cgb_resty,
+ pprTypeVariables $ cgb_tyvars,
+ pprVariables $ cgb_vars,
+ pprCorrespondingSourceBreakpoint currentModule $ cgb_tick_id
+ ]
+ -- That the 'cgb_resty' field holds the type of the breakpoint is apparent
+ -- from the fact that this field is set by
+ -- 'GHC.StgToByteCode.dehydrateCgBreakInfo' using one of its arguments and
+ -- 'GHC.StgToByteCode.dehydrateCgBreakInfo' is always invoked with this
+ -- argument set to the extension field of 'Breakpoint', which in turn holds
+ -- the type of the breakpoint according to Note [Tickish passes] and the
+ -- comment on the instance declaration of @XBreakpoint 'TickishPassStg@.
+
+-- | Constructs textual information about a type.
+pprType :: IfaceType -> SDoc
+pprType = entry (text "type") . ppr
+
+-- | Constructs textual information about type variables.
+pprTypeVariables :: [IfaceTvBndr] -> SDoc
+pprTypeVariables = entry (text "type variables") .
+ vcatOrNone .
+ map pprTypeVariableBinder
+
+-- | Constructs textual information about a type variable binder.
+pprTypeVariableBinder :: IfaceTvBndr -> SDoc
+pprTypeVariableBinder (name, kind) = ppr name <+> text "::" <+> ppr kind
+
+-- | Constructs textual information about variables.
+pprVariables :: [Maybe (IfaceIdBndr, Word)] -> SDoc
+pprVariables = entry (text "variables") . vcatOrNone . map pprVariable
+
+-- | Constructs textual information about a single variable.
+pprVariable :: Maybe (IfaceIdBndr, Word) -> SDoc
+pprVariable = maybe (text "<unknown>") (pprVariableBinder . fst)
+
+-- | Constructs textual information about a variable binder.
+pprVariableBinder :: IfaceIdBndr -> SDoc
+pprVariableBinder (multiplicity, name, type_)
+ = text "%" <> ppr multiplicity <+>
+ ppr name <+> text "::" <+> ppr type_
+
+-- | Constructs textual information about a source breakpoint corresponding to a
+-- bytecode breakpoint.
+pprCorrespondingSourceBreakpoint :: Module
+ -- ^ The enclosing module
+ -> Either InternalBreakLoc BreakpointId
+ -- ^ A reference to the source breakpoint
+ -> SDoc
+ -- ^ The textual information
+pprCorrespondingSourceBreakpoint currentModule
+ = entry (text "corresponding source breakpoint") .
+ pprBreakpointID currentModule .
+ either internalBreakLoc id
+
+-- | Constructs textual information about the ID of a source breakpoint.
+pprBreakpointID :: Module -- ^ The enclosing module
+ -> BreakpointId -- ^ The ID of the source breakpoint
+ -> SDoc -- ^ The textual information
+pprBreakpointID currentModule BreakpointId {..}
+ | bi_tick_mod == currentModule = indexDoc
+ | otherwise = indexDoc <+>
+ text "in" <+>
+ quotes (ppr bi_tick_mod)
+ where
+
+ indexDoc :: SDoc
+ indexDoc = ppr bi_tick_index
+
+-- | Constructs textual information about static-pointer table entries.
+pprStaticPointerTableEntries :: [SptEntry] -> SDoc
+pprStaticPointerTableEntries = entry (text "static-pointer table entries") .
+ vcatOrNone .
+ map pprStaticPointerTableEntry
+
+-- | Constructs textual information about a single static-pointer table entry.
+pprStaticPointerTableEntry :: SptEntry -> SDoc
+pprStaticPointerTableEntry (SptEntry name fingerprint)
+ = ppr fingerprint <> text ":" <+> ppr name
+
+-- | Constructs textual information about HPC info.
+pprHPCInfo :: Strict.Maybe ByteCodeHpcInfo -> SDoc
+pprHPCInfo = entry (text "HPC information") .
+ Strict.maybe (text "<none>") pprActualHPCInfo
+
+-- | Constructs textual information about actual HPC info.
+pprActualHPCInfo :: ByteCodeHpcInfo -> SDoc
+pprActualHPCInfo ByteCodeHpcInfo {..}
+ = vcat [
+ pprHPCInfoHash $ bchi_hash,
+ pprModuleName $ bchi_module_name,
+ pprTickBoxName $ bchi_tickbox_name,
+ pprTickCount $ bchi_tick_count
+ ]
+ where
+
+-- | Constructs textual information about the hash of HPC info.
+pprHPCInfoHash :: Int -> SDoc
+pprHPCInfoHash = entry (text "hash") . pprFixedSizeNatural
+
+-- | Constructs textual information about a module name.
+pprModuleName :: ShortByteString -> SDoc
+pprModuleName = entry (text "module name") .
+ text .
+ utf8DecodeShortByteString
+
+-- | Constructs textual information about a tick box name.
+pprTickBoxName :: ShortByteString -> SDoc
+pprTickBoxName = entry (text "tick box name") .
+ text .
+ utf8DecodeShortByteString
+
+-- | Constructs textual information about a number of tick counts.
+pprTickCount :: Int -> SDoc
+pprTickCount = entry (text "number of ticks") . ppr
+
+-- | Constructs a hexadecimal representation of a natural number such that the
+-- number of hexadecimal digits fits the number of bits used to represent the
+-- natural number.
+pprFixedSizeNatural :: (Integral a, FiniteBits a) => a -> SDoc
+pprFixedSizeNatural num
+ = assert (num >= 0) $
+ text $ replicate (digitCount - length unpadded) '0' ++ unpadded
+ where
+
+ digitCount :: Int
+ digitCount = (finiteBitSize num + 3) `div` 4
+
+ unpadded :: String
+ unpadded = showHex num ""
+
+-- | Constructs a textual representation of a boolean, interpreting 'True' and
+-- 'False' as “yes” and “no”, respectively.
+noOrYes :: Bool -> SDoc
+noOrYes bool = text (if bool then "yes" else "no")
+
+-- | Constructs an entry in a list of textual data representations.
+entry :: SDoc -- ^ The title of the entry
+ -> SDoc -- ^ The contents of the entry
+ -> SDoc -- ^ The entry
+entry title content = hang (title <> text ":") 2 content
+
+-- | Composes documents vertically in general, but presents an empty document
+-- list as `<none`>.
+vcatOrNone :: [SDoc] -> SDoc
+vcatOrNone [] = text "<none>"
+vcatOrNone docs = vcat docs
+
+-- | Composes documents vertically in general, but presents an empty document
+-- list as `<empty`>.
+vcatOrEmpty :: [SDoc] -> SDoc
+vcatOrEmpty [] = text "<empty>"
+vcatOrEmpty docs = vcat docs
=====================================
compiler/ghc.cabal.in
=====================================
@@ -217,6 +217,7 @@ Library
GHC.ByteCode.Linker
GHC.ByteCode.Recomp.Binary
GHC.ByteCode.Serialize
+ GHC.ByteCode.Show
GHC.ByteCode.Types
GHC.Cmm
GHC.Cmm.BlockId
=====================================
docs/users_guide/using.rst
=====================================
@@ -421,6 +421,13 @@ The available mode flags are:
Read the interface in ⟨file⟩ and dump it as text to ``stdout``. For
example ``ghc --show-iface M.hi``.
+.. ghc-flag:: --show-byte-code ⟨file⟩
+ :shortdesc: display contents of a bytecode file.
+ :type: mode
+ :category: modes
+
+ Read a bytecode file and dump relevant parts of it as text to ``stdout``.
+
.. ghc-flag:: --supported-extensions
--supported-languages
:shortdesc: display the supported language extensions
=====================================
ghc/GHC/Driver/Session/Mode.hs
=====================================
@@ -77,6 +77,7 @@ isShowGhciUsageMode _ = False
data PostLoadMode
= ShowInterface FilePath -- ghc --show-iface
+ | ShowByteCode FilePath -- ghc --show-byte-code
| DoMkDependHS -- ghc -M
| StopBefore StopPhase -- ghc -E | -C | -S
-- StopBefore StopLn is the default
@@ -101,6 +102,9 @@ showUnitsMode = mkPostLoadMode ShowPackages
showInterfaceMode :: FilePath -> Mode
showInterfaceMode fp = mkPostLoadMode (ShowInterface fp)
+showByteCodeMode :: FilePath -> Mode
+showByteCodeMode fp = mkPostLoadMode (ShowByteCode fp)
+
stopBeforeMode :: StopPhase -> Mode
stopBeforeMode phase = mkPostLoadMode (StopBefore phase)
@@ -231,9 +235,11 @@ mode_flags =
replaceSpace ' ' = '-'
replaceSpace c = c
] ++
- ------- interfaces ----------------------------------------------------
- [ defFlag "-show-iface" (HasArg (\f -> setMode (showInterfaceMode f)
+ ------- textual output of generated data -----------------------------
+ [ defFlag "-show-iface" (HasArg (\f -> setMode (showInterfaceMode f)
"--show-iface"))
+ , defFlag "-show-byte-code" (HasArg (\f -> setMode (showByteCodeMode f)
+ "--show-byte-code"))
------- primary modes ------------------------------------------------
, defFlag "c" (PassFlag (\f -> do setMode (stopBeforeMode NoStop) f
=====================================
ghc/Main.hs
=====================================
@@ -73,6 +73,8 @@ import GHC.SysTools.BaseDir
import GHC.Iface.Load
import GHC.Iface.Recomp.Binary ( fingerprintBinMem )
+import GHC.ByteCode.Show ( showByteCode )
+
import GHC.Tc.Utils.Monad ( initIfaceCheck )
import GHC.Iface.Errors.Ppr
@@ -267,6 +269,7 @@ main' postLoadMode units dflags0 args flagWarnings = do
(hsc_units hsc_env)
(hsc_NC hsc_env)
f
+ ShowByteCode f -> liftIO $ showByteCode logger hsc_env f
DoMake -> doMake units srcs
DoMkDependHS -> doMkDependHS (map fst srcs)
StopBefore p -> liftIO (oneShot hsc_env p srcs)
=====================================
testsuite/tests/show-bytecode/Example.hs
=====================================
@@ -0,0 +1,31 @@
+{-# LANGUAGE StaticPointers #-}
+
+module Example where
+
+import Numeric.Natural (Natural)
+import GHC.StaticPtr (StaticPtr)
+
+fibonaccis :: [Natural]
+fibonaccis = 0 : positiveFibonaccis where
+
+ positiveFibonaccis :: [Natural]
+ positiveFibonaccis = 1 : zipWith (+) fibonaccis positiveFibonaccis
+
+fibonaccisPtr :: StaticPtr [Natural]
+fibonaccisPtr = static fibonaccis
+
+divides :: Integral a => a -> a -> Bool
+k `divides` n = n `mod` k == 0
+
+primes :: [Natural]
+primes = 2 : filter isPrime [3 ..] where
+
+ isPrime :: Natural -> Bool
+ isPrime n = not (any (`divides` n) (takeWhile ((<= n) . (^ 2)) primes))
+
+primesPtr :: StaticPtr [Natural]
+primesPtr = static primes
+
+data BinTree a b = Leaf a | Node (BinTree a b) b (BinTree a b)
+
+data PerfectTree a = PerfectTree a | Nested (PerfectTree (a, a))
=====================================
testsuite/tests/show-bytecode/Makefile
=====================================
@@ -0,0 +1,23 @@
+TOP=../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+compile = '$(TEST_HC)' $(TEST_HC_OPTS) -fbyte-code -fwrite-byte-code -no-link
+show = '$(TEST_HC)' $(TEST_HC_OPTS) --show-byte-code
+normalize = sed -E -e ' \
+ s/_r[[:alnum:]]+/_@name_suffix@/g; \
+ s/[[:xdigit:]]{32}/@hash@/g; \
+ s/word [[:digit:]]{4}[[:digit:]]*/word @large_word@/ \
+ '
+
+show-bytecode-vanilla:
+ $(compile) Example.hs
+ $(show) Example.gbc | $(normalize)
+
+show-bytecode-breakpoints:
+ $(compile) -fbreak-points Example.hs
+ $(show) Example.gbc | $(normalize)
+
+show-bytecode-hpc:
+ $(compile) -fhpc Example.hs
+ $(show) Example.gbc | $(normalize)
=====================================
testsuite/tests/show-bytecode/all.T
=====================================
@@ -0,0 +1,18 @@
+test(
+ 'show-bytecode-vanilla',
+ extra_files(['Example.hs']),
+ makefile_test,
+ []
+)
+test(
+ 'show-bytecode-breakpoints',
+ extra_files(['Example.hs']),
+ makefile_test,
+ []
+)
+test(
+ 'show-bytecode-hpc',
+ extra_files(['Example.hs']),
+ makefile_test,
+ []
+)
=====================================
testsuite/tests/show-bytecode/show-bytecode-breakpoints.stdout
=====================================
@@ -0,0 +1,828 @@
+[1 of 1] Compiling Example ( Example.hs, Example.gbc )
+name: Example
+hash: @hash@
+objects:
+ ordinary object ‘primesPtr’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 0
+ utilized items:
+ break array of module ‘Example’
+ item named ‘static_ptr1’
+ item named ‘$dTypeable2_@name_suffix@’
+ item named ‘$fIsStaticStaticPtr’
+ static-construction object ‘static_ptr1’:
+ data constructor name: StaticPtr
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘primes’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: StaticPtrInfo
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "main"
+ utilized items:
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "Example"
+ utilized items:
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: (,)
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 27
+ utilized items: <none>
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 20
+ utilized items: <none>
+ ordinary object ‘primes’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 2
+ info table of ‘:’
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘primes_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 1
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘primes_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘primes_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ word 3
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ item named ‘$fEnumNatural’
+ item named ‘enumFrom’
+ item named ‘isPrime_@name_suffix@’
+ item named ‘filter’
+ ordinary object ‘primes_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ word 2
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ ordinary object ‘isPrime_@name_suffix@’:
+ arity: 1
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 9
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 8
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 7
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 6
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 5
+ word 2
+ info table of ‘IS’
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘v_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$fIntegralInteger’
+ item named ‘$fNumNatural’
+ item named ‘^’
+ ordinary object ‘pap_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: <none>
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 4
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘v_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$fOrdNatural’
+ item named ‘<=’
+ ordinary object ‘pap_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: <none>
+ item named ‘.’
+ item named ‘primes’
+ item named ‘takeWhile’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 3
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘pap_@name_suffix@’:
+ arity: 2
+ literals: <none>
+ utilized items:
+ item named ‘$fIntegralNatural’
+ item named ‘divides’
+ item named ‘$fFoldableList’
+ item named ‘any’
+ item named ‘not’
+ ordinary object ‘fibonaccisPtr’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 10
+ utilized items:
+ break array of module ‘Example’
+ item named ‘static_ptr’
+ item named ‘$dTypeable2_@name_suffix@’
+ item named ‘$fIsStaticStaticPtr’
+ static-construction object ‘static_ptr’:
+ data constructor name: StaticPtr
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘fibonaccis’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: StaticPtrInfo
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "main"
+ utilized items:
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "Example"
+ utilized items:
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: (,)
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 15
+ utilized items: <none>
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 24
+ utilized items: <none>
+ ordinary object ‘fibonaccis’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 11
+ info table of ‘:’
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘fibonaccis_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ word 0
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ item named ‘positiveFibonaccis_@name_suffix@’
+ ordinary object ‘positiveFibonaccis_@name_suffix@’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 13
+ info table of ‘:’
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘positiveFibonaccis_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 12
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘positiveFibonaccis_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘+’
+ item named ‘positiveFibonaccis_@name_suffix@’
+ item named ‘fibonaccis’
+ item named ‘zipWith’
+ ordinary object ‘positiveFibonaccis_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ word 1
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ ordinary object ‘$dTypeable2_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$dTypeable_@name_suffix@’
+ item named ‘$dTypeable1_@name_suffix@’
+ item named ‘mkTrAppChecked’
+ ordinary object ‘$dTypeable1_@name_suffix@’:
+ arity: 0
+ literals: info table of ‘[]’
+ utilized items:
+ item named ‘$tcList’
+ item named ‘mkTrCon’
+ ordinary object ‘$dTypeable_@name_suffix@’:
+ arity: 0
+ literals: info table of ‘[]’
+ utilized items:
+ item named ‘$tcNatural’
+ item named ‘mkTrCon’
+ static-construction object ‘$tc'Nested’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 1
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Nested2_@name_suffix@’
+ item named ‘$krep17_@name_suffix@’
+ static-construction object ‘$tc'Nested2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Nested1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep17_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep16_@name_suffix@’
+ item named ‘$krep13_@name_suffix@’
+ static-construction object ‘$krep16_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcPerfectTree’
+ item named ‘$krep15_@name_suffix@’
+ static-construction object ‘$krep15_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep4_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tc'PerfectTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 1
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'PerfectTree2_@name_suffix@’
+ item named ‘$krep14_@name_suffix@’
+ static-construction object ‘$tc'PerfectTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'PerfectTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep14_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep13_@name_suffix@’
+ static-construction object ‘$krep13_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcPerfectTree’
+ item named ‘$krep12_@name_suffix@’
+ static-construction object ‘$krep12_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tcPerfectTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 0
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tcPerfectTree2_@name_suffix@’
+ item named ‘krep$*Arr*’
+ static-construction object ‘$tcPerfectTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tcPerfectTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$tc'Node’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 2
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Node2_@name_suffix@’
+ item named ‘$krep11_@name_suffix@’
+ static-construction object ‘$tc'Node2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Node1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep11_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep7_@name_suffix@’
+ item named ‘$krep10_@name_suffix@’
+ static-construction object ‘$krep10_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep_@name_suffix@’
+ item named ‘$krep9_@name_suffix@’
+ static-construction object ‘$krep9_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep7_@name_suffix@’
+ item named ‘$krep7_@name_suffix@’
+ static-construction object ‘$tc'Leaf’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 2
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Leaf2_@name_suffix@’
+ item named ‘$krep8_@name_suffix@’
+ static-construction object ‘$tc'Leaf2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Leaf1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep8_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep7_@name_suffix@’
+ static-construction object ‘$krep7_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcBinTree’
+ item named ‘$krep6_@name_suffix@’
+ static-construction object ‘$krep6_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep5_@name_suffix@’
+ static-construction object ‘$krep5_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tcBinTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 0
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tcBinTree2_@name_suffix@’
+ item named ‘krep$*->*->*’
+ static-construction object ‘$tcBinTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tcBinTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep4_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcTuple2’
+ item named ‘$krep3_@name_suffix@’
+ static-construction object ‘$krep3_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep2_@name_suffix@’
+ static-construction object ‘$krep2_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$krep1_@name_suffix@’:
+ data constructor name: KindRepVar
+ lifted: yes
+ literals: word 0
+ utilized items: <none>
+ static-construction object ‘$krep_@name_suffix@’:
+ data constructor name: KindRepVar
+ lifted: yes
+ literals: word 1
+ utilized items: <none>
+ static-construction object ‘$trModule’:
+ data constructor name: Module
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$trModule2_@name_suffix@’
+ item named ‘$trModule4_@name_suffix@’
+ static-construction object ‘$trModule4_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$trModule3_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$trModule2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$trModule1_@name_suffix@’
+ utilized items: <none>
+ ordinary object ‘divides’:
+ arity: 3
+ literals: <none>
+ utilized items:
+ ordinary object ‘$dReal_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘$dNum_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘$dEq_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘$dEq1_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘bcprep_@name_suffix@’:
+ arity: 5
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 15
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ word 0
+ info table of ‘IS’
+ utilized items: item named ‘fromInteger’
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 3
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 14
+ utilized items:
+ break array of module ‘Example’
+ item named ‘mod’
+ item named ‘==’
+ item named ‘$p1Ord’
+ item named ‘$p2Real’
+ item named ‘$p1Real’
+ item named ‘$p1Integral’
+ ordinary object ‘Node’:
+ arity: 3
+ literals: info table of ‘Node’
+ utilized items: <none>
+ ordinary object ‘Leaf’:
+ arity: 1
+ literals: info table of ‘Leaf’
+ utilized items: <none>
+ ordinary object ‘Nested’:
+ arity: 1
+ literals: info table of ‘Nested’
+ utilized items: <none>
+ ordinary object ‘PerfectTree’:
+ arity: 1
+ literals: info table of ‘PerfectTree’
+ utilized items: <none>
+data constructor info tables:
+ info table of ‘PerfectTree’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Nested’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Leaf’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Node’:
+ number of words for pointers: 3
+ number of words for non-pointers: 0
+top-level strings:
+ $tc'Nested1_@name_suffix@: "'Nested"
+ $tc'PerfectTree1_@name_suffix@: "'PerfectTree"
+ $tcPerfectTree1_@name_suffix@: "PerfectTree"
+ $tc'Node1_@name_suffix@: "'Node"
+ $tc'Leaf1_@name_suffix@: "'Leaf"
+ $tcBinTree1_@name_suffix@: "BinTree"
+ $trModule3_@name_suffix@: "Example"
+ $trModule1_@name_suffix@: "main"
+breakpoints:
+ source breakpoints:
+ source breakpoint 0:
+ source span: Example.hs:18:17-25
+ declaration path: divides
+ free variables:
+ k
+ n
+ source breakpoint 1:
+ source span: Example.hs:18:17-30
+ declaration path: divides
+ free variables:
+ k
+ n
+ source breakpoint 2:
+ source span: Example.hs:24:27-37
+ declaration path:
+ primes
+ isPrime
+ free variables: n
+ source breakpoint 3:
+ source span: Example.hs:24:53-56
+ declaration path:
+ primes
+ isPrime
+ free variables: n
+ source breakpoint 4:
+ source span: Example.hs:24:62-64
+ declaration path:
+ primes
+ isPrime
+ free variables: <none>
+ source breakpoint 5:
+ source span: Example.hs:24:52-65
+ declaration path:
+ primes
+ isPrime
+ free variables: n
+ source breakpoint 6:
+ source span: Example.hs:24:41-73
+ declaration path:
+ primes
+ isPrime
+ free variables: n
+ source breakpoint 7:
+ source span: Example.hs:24:22-74
+ declaration path:
+ primes
+ isPrime
+ free variables: n
+ source breakpoint 8:
+ source span: Example.hs:24:17-75
+ declaration path:
+ primes
+ isPrime
+ free variables: n
+ source breakpoint 9:
+ source span: Example.hs:21:14-34
+ declaration path: primes
+ free variables: isPrime
+ source breakpoint 10:
+ source span: Example.hs:21:10-34
+ declaration path: primes
+ free variables: isPrime
+ source breakpoint 11:
+ source span: Example.hs:27:13-25
+ declaration path: primesPtr
+ free variables: <none>
+ source breakpoint 12:
+ source span: Example.hs:12:30-70
+ declaration path:
+ fibonaccis
+ positiveFibonaccis
+ free variables: positiveFibonaccis
+ source breakpoint 13:
+ source span: Example.hs:12:26-70
+ declaration path:
+ fibonaccis
+ positiveFibonaccis
+ free variables: positiveFibonaccis
+ source breakpoint 14:
+ source span: Example.hs:9:14-35
+ declaration path: fibonaccis
+ free variables: positiveFibonaccis
+ source breakpoint 15:
+ source span: Example.hs:15:17-33
+ declaration path: fibonaccisPtr
+ free variables: <none>
+ bytecode breakpoints:
+ bytecode breakpoint 0:
+ type: StaticPtr [Natural]
+ type variables: <none>
+ variables: <none>
+ corresponding source breakpoint: 11
+ bytecode breakpoint 1:
+ type: [Natural]
+ type variables: <none>
+ variables: <unknown>
+ corresponding source breakpoint: 9
+ bytecode breakpoint 2:
+ type: [Natural]
+ type variables: <none>
+ variables: <unknown>
+ corresponding source breakpoint: 10
+ bytecode breakpoint 3:
+ type: Natural -> Bool
+ type variables: <none>
+ variables: %'Many n :: Natural
+ corresponding source breakpoint: 2
+ bytecode breakpoint 4:
+ type: Natural -> Bool
+ type variables: <none>
+ variables: %'Many n :: Natural
+ corresponding source breakpoint: 3
+ bytecode breakpoint 5:
+ type: Natural -> Natural
+ type variables: <none>
+ variables: <none>
+ corresponding source breakpoint: 4
+ bytecode breakpoint 6:
+ type: Natural -> Bool
+ type variables: <none>
+ variables: %'Many n :: Natural
+ corresponding source breakpoint: 5
+ bytecode breakpoint 7:
+ type: [Natural]
+ type variables: <none>
+ variables: %'Many n :: Natural
+ corresponding source breakpoint: 6
+ bytecode breakpoint 8:
+ type: Bool
+ type variables: <none>
+ variables: %'Many n :: Natural
+ corresponding source breakpoint: 7
+ bytecode breakpoint 9:
+ type: Bool
+ type variables: <none>
+ variables: %'Many n :: Natural
+ corresponding source breakpoint: 8
+ bytecode breakpoint 10:
+ type: StaticPtr [Natural]
+ type variables: <none>
+ variables: <none>
+ corresponding source breakpoint: 15
+ bytecode breakpoint 11:
+ type: [Natural]
+ type variables: <none>
+ variables: <unknown>
+ corresponding source breakpoint: 14
+ bytecode breakpoint 12:
+ type: [Natural]
+ type variables: <none>
+ variables: <unknown>
+ corresponding source breakpoint: 12
+ bytecode breakpoint 13:
+ type: [Natural]
+ type variables: <none>
+ variables: <unknown>
+ corresponding source breakpoint: 13
+ bytecode breakpoint 14:
+ type: a
+ type variables: a :: *
+ variables:
+ %'Many eta :: a
+ %'Many eta1 :: a
+ corresponding source breakpoint: 0
+ bytecode breakpoint 15:
+ type: Bool
+ type variables: a :: *
+ variables:
+ %'Many eta :: a
+ %'Many eta1 :: a
+ corresponding source breakpoint: 1
+static-pointer table entries:
+ @hash@: static_ptr
+ @hash@: static_ptr1
+HPC information: <none>
+
=====================================
testsuite/tests/show-bytecode/show-bytecode-hpc.stdout
=====================================
@@ -0,0 +1,668 @@
+[1 of 1] Compiling Example ( Example.hs, Example.gbc )
+name: Example
+hash: @hash@
+objects:
+ ordinary object ‘primesPtr’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ item named ‘static_ptr1’
+ item named ‘$dTypeable2_@name_suffix@’
+ item named ‘$fIsStaticStaticPtr’
+ static-construction object ‘static_ptr1’:
+ data constructor name: StaticPtr
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: StaticPtrInfo
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "main"
+ utilized items:
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "Example"
+ utilized items:
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: (,)
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 27
+ utilized items: <none>
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 20
+ utilized items: <none>
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: item named ‘primes’
+ ordinary object ‘primes2_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘primes2_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘primes2_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ word 3
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ item named ‘$fEnumNatural’
+ item named ‘enumFrom’
+ ordinary object ‘primes2_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: item named ‘isPrime_@name_suffix@’
+ item named ‘filter’
+ ordinary object ‘isPrime_@name_suffix@’:
+ arity: 1
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: item named ‘primes’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘v_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ item named ‘$fIntegralInteger’
+ item named ‘$fNumNatural’
+ item named ‘^’
+ ordinary object ‘v1_@name_suffix@’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ word 2
+ info table of ‘IS’
+ utilized items: <none>
+ ordinary object ‘pap_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: <none>
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘v_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ item named ‘$fOrdNatural’
+ item named ‘<=’
+ ordinary object ‘v1_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: <none>
+ ordinary object ‘pap_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: <none>
+ item named ‘.’
+ item named ‘takeWhile’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘v_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘pap_@name_suffix@’:
+ arity: 2
+ literals: <none>
+ utilized items:
+ item named ‘$fIntegralNatural’
+ item named ‘divides’
+ ordinary object ‘v1_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: <none>
+ ordinary object ‘pap_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: <none>
+ item named ‘$fFoldableList’
+ item named ‘any’
+ item named ‘not’
+ ordinary object ‘primes’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ label ‘_hpc_tickboxes_Example_hpc’
+ info table of ‘:’
+ utilized items:
+ item named ‘primes2_@name_suffix@’
+ item named ‘primes1_@name_suffix@’
+ ordinary object ‘primes1_@name_suffix@’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ word 2
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ ordinary object ‘fibonaccisPtr’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ item named ‘static_ptr’
+ item named ‘$dTypeable2_@name_suffix@’
+ item named ‘$fIsStaticStaticPtr’
+ static-construction object ‘static_ptr’:
+ data constructor name: StaticPtr
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: StaticPtrInfo
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "main"
+ utilized items:
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "Example"
+ utilized items:
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: (,)
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 15
+ utilized items: <none>
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 24
+ utilized items: <none>
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: item named ‘fibonaccis’
+ ordinary object ‘positiveFibonaccis1_@name_suffix@’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ label ‘_hpc_tickboxes_Example_hpc’
+ info table of ‘:’
+ utilized items:
+ item named ‘positiveFibonaccis2_@name_suffix@’
+ item named ‘positiveFibonaccis_@name_suffix@’
+ ordinary object ‘positiveFibonaccis2_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘positiveFibonaccis2_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: item named ‘positiveFibonaccis1_@name_suffix@’
+ ordinary object ‘positiveFibonaccis2_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: item named ‘fibonaccis’
+ ordinary object ‘positiveFibonaccis2_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘+’
+ item named ‘zipWith’
+ ordinary object ‘fibonaccis’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ label ‘_hpc_tickboxes_Example_hpc’
+ info table of ‘:’
+ utilized items:
+ item named ‘fibonaccis2_@name_suffix@’
+ item named ‘fibonaccis1_@name_suffix@’
+ ordinary object ‘fibonaccis2_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: item named ‘positiveFibonaccis1_@name_suffix@’
+ ordinary object ‘positiveFibonaccis_@name_suffix@’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ word 1
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ ordinary object ‘fibonaccis1_@name_suffix@’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ word 0
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ ordinary object ‘$dTypeable2_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$dTypeable_@name_suffix@’
+ item named ‘$dTypeable1_@name_suffix@’
+ item named ‘mkTrAppChecked’
+ ordinary object ‘$dTypeable1_@name_suffix@’:
+ arity: 0
+ literals: info table of ‘[]’
+ utilized items:
+ item named ‘$tcList’
+ item named ‘mkTrCon’
+ ordinary object ‘$dTypeable_@name_suffix@’:
+ arity: 0
+ literals: info table of ‘[]’
+ utilized items:
+ item named ‘$tcNatural’
+ item named ‘mkTrCon’
+ static-construction object ‘$tc'Nested’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 1
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Nested2_@name_suffix@’
+ item named ‘$krep17_@name_suffix@’
+ static-construction object ‘$tc'Nested2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Nested1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep17_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep16_@name_suffix@’
+ item named ‘$krep13_@name_suffix@’
+ static-construction object ‘$krep16_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcPerfectTree’
+ item named ‘$krep15_@name_suffix@’
+ static-construction object ‘$krep15_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep4_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tc'PerfectTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 1
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'PerfectTree2_@name_suffix@’
+ item named ‘$krep14_@name_suffix@’
+ static-construction object ‘$tc'PerfectTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'PerfectTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep14_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep13_@name_suffix@’
+ static-construction object ‘$krep13_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcPerfectTree’
+ item named ‘$krep12_@name_suffix@’
+ static-construction object ‘$krep12_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tcPerfectTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 0
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tcPerfectTree2_@name_suffix@’
+ item named ‘krep$*Arr*’
+ static-construction object ‘$tcPerfectTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tcPerfectTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$tc'Node’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 2
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Node2_@name_suffix@’
+ item named ‘$krep11_@name_suffix@’
+ static-construction object ‘$tc'Node2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Node1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep11_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep7_@name_suffix@’
+ item named ‘$krep10_@name_suffix@’
+ static-construction object ‘$krep10_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep_@name_suffix@’
+ item named ‘$krep9_@name_suffix@’
+ static-construction object ‘$krep9_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep7_@name_suffix@’
+ item named ‘$krep7_@name_suffix@’
+ static-construction object ‘$tc'Leaf’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 2
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Leaf2_@name_suffix@’
+ item named ‘$krep8_@name_suffix@’
+ static-construction object ‘$tc'Leaf2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Leaf1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep8_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep7_@name_suffix@’
+ static-construction object ‘$krep7_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcBinTree’
+ item named ‘$krep6_@name_suffix@’
+ static-construction object ‘$krep6_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep5_@name_suffix@’
+ static-construction object ‘$krep5_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tcBinTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 0
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tcBinTree2_@name_suffix@’
+ item named ‘krep$*->*->*’
+ static-construction object ‘$tcBinTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tcBinTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep4_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcTuple2’
+ item named ‘$krep3_@name_suffix@’
+ static-construction object ‘$krep3_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep2_@name_suffix@’
+ static-construction object ‘$krep2_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$krep1_@name_suffix@’:
+ data constructor name: KindRepVar
+ lifted: yes
+ literals: word 0
+ utilized items: <none>
+ static-construction object ‘$krep_@name_suffix@’:
+ data constructor name: KindRepVar
+ lifted: yes
+ literals: word 1
+ utilized items: <none>
+ static-construction object ‘$trModule’:
+ data constructor name: Module
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$trModule2_@name_suffix@’
+ item named ‘$trModule4_@name_suffix@’
+ static-construction object ‘$trModule4_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$trModule3_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$trModule2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$trModule1_@name_suffix@’
+ utilized items: <none>
+ ordinary object ‘divides’:
+ arity: 3
+ literals: <none>
+ utilized items:
+ ordinary object ‘$dReal_@name_suffix@’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ word 0
+ info table of ‘IS’
+ utilized items:
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘fromInteger’
+ item named ‘$p1Real’
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 3
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: <none>
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: <none>
+ item named ‘mod’
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘==’
+ item named ‘$p1Ord’
+ item named ‘$p2Real’
+ item named ‘$p1Integral’
+ ordinary object ‘Node’:
+ arity: 3
+ literals: info table of ‘Node’
+ utilized items: <none>
+ ordinary object ‘Leaf’:
+ arity: 1
+ literals: info table of ‘Leaf’
+ utilized items: <none>
+ ordinary object ‘Nested’:
+ arity: 1
+ literals: info table of ‘Nested’
+ utilized items: <none>
+ ordinary object ‘PerfectTree’:
+ arity: 1
+ literals: info table of ‘PerfectTree’
+ utilized items: <none>
+data constructor info tables:
+ info table of ‘PerfectTree’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Nested’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Leaf’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Node’:
+ number of words for pointers: 3
+ number of words for non-pointers: 0
+top-level strings:
+ $tc'Nested1_@name_suffix@: "'Nested"
+ $tc'PerfectTree1_@name_suffix@: "'PerfectTree"
+ $tcPerfectTree1_@name_suffix@: "PerfectTree"
+ $tc'Node1_@name_suffix@: "'Node"
+ $tc'Leaf1_@name_suffix@: "'Leaf"
+ $tcBinTree1_@name_suffix@: "BinTree"
+ $trModule3_@name_suffix@: "Example"
+ $trModule1_@name_suffix@: "main"
+breakpoints: <none>
+static-pointer table entries:
+ @hash@: static_ptr
+ @hash@: static_ptr1
+HPC information:
+ hash: 000000006110204f
+ module name: Example
+ tick box name: _hpc_tickboxes_Example_hpc
+ number of ticks: 45
+
=====================================
testsuite/tests/show-bytecode/show-bytecode-vanilla.stdout
=====================================
@@ -0,0 +1,593 @@
+[1 of 1] Compiling Example ( Example.hs, Example.gbc )
+name: Example
+hash: @hash@
+objects:
+ ordinary object ‘primesPtr’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr1’
+ item named ‘$dTypeable2_@name_suffix@’
+ item named ‘$fIsStaticStaticPtr’
+ static-construction object ‘static_ptr1’:
+ data constructor name: StaticPtr
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘primes’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: StaticPtrInfo
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "main"
+ utilized items:
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "Example"
+ utilized items:
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: (,)
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 27
+ utilized items: <none>
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 20
+ utilized items: <none>
+ ordinary object ‘primes2_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘primes2_sat_@name_suffix@’
+ item named ‘isPrime_@name_suffix@’
+ item named ‘filter’
+ ordinary object ‘isPrime_@name_suffix@’:
+ arity: 1
+ literals: <none>
+ utilized items:
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals: <none>
+ utilized items:
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals: <none>
+ utilized items:
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ word 2
+ info table of ‘IS’
+ utilized items:
+ ordinary object ‘v_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$fIntegralInteger’
+ item named ‘$fNumNatural’
+ item named ‘^’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: <none>
+ ordinary object ‘v_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$fOrdNatural’
+ item named ‘<=’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: <none>
+ item named ‘.’
+ item named ‘primes’
+ item named ‘takeWhile’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 2
+ literals: <none>
+ utilized items:
+ item named ‘$fIntegralNatural’
+ item named ‘divides’
+ item named ‘$fFoldableList’
+ item named ‘any’
+ item named ‘not’
+ static-construction object ‘primes’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘primes1_@name_suffix@’
+ item named ‘primes2_@name_suffix@’
+ ordinary object ‘primes2_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘primes2_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ word 3
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ item named ‘$fEnumNatural’
+ item named ‘enumFrom’
+ ordinary object ‘primes1_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘primes1_sat_@name_suffix@’
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ static-construction object ‘primes1_sat_@name_suffix@’:
+ data constructor name: IS
+ lifted: yes
+ literals: word 2
+ utilized items: <none>
+ ordinary object ‘fibonaccisPtr’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr’
+ item named ‘$dTypeable2_@name_suffix@’
+ item named ‘$fIsStaticStaticPtr’
+ static-construction object ‘static_ptr’:
+ data constructor name: StaticPtr
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘fibonaccis’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: StaticPtrInfo
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "main"
+ utilized items:
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "Example"
+ utilized items:
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: (,)
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 15
+ utilized items: <none>
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 24
+ utilized items: <none>
+ ordinary object ‘positiveFibonaccis2_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘positiveFibonaccis1_@name_suffix@’
+ item named ‘fibonaccis’
+ item named ‘positiveFibonaccis2_sat_@name_suffix@’
+ item named ‘zipWith’
+ static-construction object ‘positiveFibonaccis1_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘positiveFibonaccis_@name_suffix@’
+ item named ‘positiveFibonaccis2_@name_suffix@’
+ static-construction object ‘fibonaccis’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘fibonaccis1_@name_suffix@’
+ item named ‘positiveFibonaccis1_@name_suffix@’
+ ordinary object ‘positiveFibonaccis2_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘+’
+ ordinary object ‘positiveFibonaccis_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘positiveFibonaccis_sat_@name_suffix@’
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ static-construction object ‘positiveFibonaccis_sat_@name_suffix@’:
+ data constructor name: IS
+ lifted: yes
+ literals: word 1
+ utilized items: <none>
+ ordinary object ‘fibonaccis1_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘fibonaccis1_sat_@name_suffix@’
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ static-construction object ‘fibonaccis1_sat_@name_suffix@’:
+ data constructor name: IS
+ lifted: yes
+ literals: word 0
+ utilized items: <none>
+ ordinary object ‘$dTypeable2_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$dTypeable_@name_suffix@’
+ item named ‘$dTypeable1_@name_suffix@’
+ item named ‘mkTrAppChecked’
+ ordinary object ‘$dTypeable1_@name_suffix@’:
+ arity: 0
+ literals: info table of ‘[]’
+ utilized items:
+ item named ‘$tcList’
+ item named ‘mkTrCon’
+ ordinary object ‘$dTypeable_@name_suffix@’:
+ arity: 0
+ literals: info table of ‘[]’
+ utilized items:
+ item named ‘$tcNatural’
+ item named ‘mkTrCon’
+ static-construction object ‘$tc'Nested’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 1
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Nested2_@name_suffix@’
+ item named ‘$krep17_@name_suffix@’
+ static-construction object ‘$tc'Nested2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Nested1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep17_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep16_@name_suffix@’
+ item named ‘$krep13_@name_suffix@’
+ static-construction object ‘$krep16_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcPerfectTree’
+ item named ‘$krep15_@name_suffix@’
+ static-construction object ‘$krep15_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep4_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tc'PerfectTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 1
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'PerfectTree2_@name_suffix@’
+ item named ‘$krep14_@name_suffix@’
+ static-construction object ‘$tc'PerfectTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'PerfectTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep14_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep13_@name_suffix@’
+ static-construction object ‘$krep13_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcPerfectTree’
+ item named ‘$krep12_@name_suffix@’
+ static-construction object ‘$krep12_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tcPerfectTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 0
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tcPerfectTree2_@name_suffix@’
+ item named ‘krep$*Arr*’
+ static-construction object ‘$tcPerfectTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tcPerfectTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$tc'Node’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 2
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Node2_@name_suffix@’
+ item named ‘$krep11_@name_suffix@’
+ static-construction object ‘$tc'Node2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Node1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep11_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep7_@name_suffix@’
+ item named ‘$krep10_@name_suffix@’
+ static-construction object ‘$krep10_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep_@name_suffix@’
+ item named ‘$krep9_@name_suffix@’
+ static-construction object ‘$krep9_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep7_@name_suffix@’
+ item named ‘$krep7_@name_suffix@’
+ static-construction object ‘$tc'Leaf’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 2
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Leaf2_@name_suffix@’
+ item named ‘$krep8_@name_suffix@’
+ static-construction object ‘$tc'Leaf2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Leaf1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep8_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep7_@name_suffix@’
+ static-construction object ‘$krep7_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcBinTree’
+ item named ‘$krep6_@name_suffix@’
+ static-construction object ‘$krep6_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep5_@name_suffix@’
+ static-construction object ‘$krep5_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tcBinTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 0
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tcBinTree2_@name_suffix@’
+ item named ‘krep$*->*->*’
+ static-construction object ‘$tcBinTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tcBinTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep4_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcTuple2’
+ item named ‘$krep3_@name_suffix@’
+ static-construction object ‘$krep3_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep2_@name_suffix@’
+ static-construction object ‘$krep2_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$krep1_@name_suffix@’:
+ data constructor name: KindRepVar
+ lifted: yes
+ literals: word 0
+ utilized items: <none>
+ static-construction object ‘$krep_@name_suffix@’:
+ data constructor name: KindRepVar
+ lifted: yes
+ literals: word 1
+ utilized items: <none>
+ static-construction object ‘$trModule’:
+ data constructor name: Module
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$trModule2_@name_suffix@’
+ item named ‘$trModule4_@name_suffix@’
+ static-construction object ‘$trModule4_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$trModule3_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$trModule2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$trModule1_@name_suffix@’
+ utilized items: <none>
+ ordinary object ‘divides’:
+ arity: 3
+ literals: <none>
+ utilized items:
+ ordinary object ‘$dReal_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ word 0
+ info table of ‘IS’
+ utilized items:
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘fromInteger’
+ item named ‘$p1Real’
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: item named ‘mod’
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘==’
+ item named ‘$p1Ord’
+ item named ‘$p2Real’
+ item named ‘$p1Integral’
+ ordinary object ‘Node’:
+ arity: 3
+ literals: info table of ‘Node’
+ utilized items: <none>
+ ordinary object ‘Leaf’:
+ arity: 1
+ literals: info table of ‘Leaf’
+ utilized items: <none>
+ ordinary object ‘Nested’:
+ arity: 1
+ literals: info table of ‘Nested’
+ utilized items: <none>
+ ordinary object ‘PerfectTree’:
+ arity: 1
+ literals: info table of ‘PerfectTree’
+ utilized items: <none>
+data constructor info tables:
+ info table of ‘PerfectTree’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Nested’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Leaf’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Node’:
+ number of words for pointers: 3
+ number of words for non-pointers: 0
+top-level strings:
+ $tc'Nested1_@name_suffix@: "'Nested"
+ $tc'PerfectTree1_@name_suffix@: "'PerfectTree"
+ $tcPerfectTree1_@name_suffix@: "PerfectTree"
+ $tc'Node1_@name_suffix@: "'Node"
+ $tc'Leaf1_@name_suffix@: "'Leaf"
+ $tcBinTree1_@name_suffix@: "BinTree"
+ $trModule3_@name_suffix@: "Example"
+ $trModule1_@name_suffix@: "main"
+breakpoints: <none>
+static-pointer table entries:
+ @hash@: static_ptr
+ @hash@: static_ptr1
+HPC information: <none>
+
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1758ebbafed11feda9247f2025ebbea…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/1758ebbafed11feda9247f2025ebbea…
You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
1
0
[Git][ghc/ghc][wip/jeltsch/textual-bytecode-output] Add support for textual output of bytecode file content
by Wolfgang Jeltsch (@jeltsch) 21 Jul '26
by Wolfgang Jeltsch (@jeltsch) 21 Jul '26
21 Jul '26
Wolfgang Jeltsch pushed to branch wip/jeltsch/textual-bytecode-output at Glasgow Haskell Compiler / GHC
Commits:
c72054cd by Wolfgang Jeltsch at 2026-07-21T17:19:14+03:00
Add support for textual output of bytecode file content
This resolves #26909.
- - - - -
13 changed files:
- + changelog.d/show-byte-code
- compiler/GHC/ByteCode/Serialize.hs
- + compiler/GHC/ByteCode/Show.hs
- compiler/ghc.cabal.in
- docs/users_guide/using.rst
- ghc/GHC/Driver/Session/Mode.hs
- ghc/Main.hs
- + testsuite/tests/show-bytecode/Example.hs
- + testsuite/tests/show-bytecode/Makefile
- + testsuite/tests/show-bytecode/all.T
- + testsuite/tests/show-bytecode/show-bytecode-breakpoints.stdout
- + testsuite/tests/show-bytecode/show-bytecode-hpc.stdout
- + testsuite/tests/show-bytecode/show-bytecode-vanilla.stdout
Changes:
=====================================
changelog.d/show-byte-code
=====================================
@@ -0,0 +1,8 @@
+section: bytecode
+synopsis: Add support for textual output of bytecode file content
+issues: #26909
+mrs: !_____
+description: {
+ There is now an option `--show-byte-code` for outputting relevant
+ content of a bytecode file in textual form.
+}
=====================================
compiler/GHC/ByteCode/Serialize.hs
=====================================
@@ -6,7 +6,7 @@
{- | This module implements the serialization of bytecode objects to and from disk.
-}
module GHC.ByteCode.Serialize
- ( writeBinByteCode, readBinByteCode
+ ( writeBinByteCode, readBinByteCode, readOnDiskModuleByteCode
, ModuleByteCode(..)
, BytecodeLibX(..)
, BytecodeLib
=====================================
compiler/GHC/ByteCode/Show.hs
=====================================
@@ -0,0 +1,531 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE RecordWildCards #-}
+
+-- | This module implements the output of textual information about the contents
+-- of bytecode files. It is the backbone of the @--show-byte-code@ option.
+module GHC.ByteCode.Show (showByteCode) where
+
+import Prelude ((+), (-), Integral, div)
+import Control.Arrow ((>>>))
+import Control.Exception (assert)
+import Data.Eq ((==))
+import Data.Ord ((>=))
+import Data.Bits (FiniteBits, finiteBitSize)
+import Data.Function (($), id, (.))
+import Data.Tuple (fst, uncurry)
+import Data.Bool (Bool, otherwise, not)
+import Data.Int (Int)
+import Data.Word (Word)
+import Data.Maybe (Maybe, maybe)
+import Data.Either (Either, either)
+import Data.List (length, (++), map, zipWith4, take, drop, replicate)
+import Data.String (String)
+import Data.ByteString (ByteString)
+import Data.ByteString.Short (ShortByteString)
+import Data.IntMap (IntMap)
+import Data.IntMap qualified as IntMap (toList)
+import Data.Array (bounds, indices, elems)
+import Numeric (showHex)
+import Text.Show (show)
+import System.IO (IO, FilePath)
+import GHC.Data.Strict qualified as Strict (Maybe, maybe)
+import GHC.Data.FastString (unpackFS)
+import GHC.Data.FlatBag (FlatBag, elemsFlatBag)
+import GHC.Fingerprint (Fingerprint)
+import GHC.Types.SrcLoc (noSrcSpan)
+import GHC.Types.Name (Name)
+import GHC.Types.Name.Occurrence (OccName)
+import GHC.Types.Tickish (BreakTickIndex, BreakpointId (..))
+import GHC.Types.SptEntry (SptEntry (..))
+import GHC.Types.Error (MessageClass (MCDump))
+import GHC.Utils.Logger (Logger, logMsg)
+import GHC.Utils.Binary (BinSrcSpan (..))
+import GHC.Utils.Encoding.UTF8 (utf8DecodeShortByteString, utf8DecodeByteString)
+import GHC.Utils.Outputable
+ (
+ defaultDumpStyle,
+ SDoc,
+ text,
+ (<>),
+ (<+>),
+ quotes,
+ hsep,
+ vcat,
+ hang,
+ withPprStyle,
+ ppr
+ )
+import GHC.Unit.Types (Module)
+import GHC.Iface.Type (IfaceType, IfaceTvBndr, IfaceIdBndr)
+import GHC.HsToCore.Breakpoints (ModBreaks (..))
+import GHC.ByteCode.Types
+ (
+ FFIInfo (..),
+ BCONPtr (..),
+ BCOPtr (..),
+ UnlinkedBCO (..),
+ ByteCodeHpcInfo (..),
+ CompiledByteCode (..)
+ )
+import GHC.ByteCode.Breakpoints
+ (
+ InternalBreakpointId (..),
+ InternalBreakLoc (..),
+ CgBreakInfo (..),
+ InternalModBreaks (..)
+ )
+import GHC.ByteCode.Binary (OnDiskModuleByteCode (..))
+import GHC.ByteCode.Serialize (readOnDiskModuleByteCode)
+import GHC.Driver.Env.Types (HscEnv)
+import GHCi.FFI (FFIType)
+import GHCi.Message (ConInfoTable (..))
+
+-- | Outputs textual information about the contents of a bytecode file.
+showByteCode :: Logger -> HscEnv -> FilePath -> IO ()
+showByteCode logger env path = do
+ byteCode <- readOnDiskModuleByteCode env path
+ logMsg logger
+ MCDump
+ noSrcSpan
+ (withPprStyle defaultDumpStyle $ pprOnDiskModuleByteCode byteCode)
+
+-- | Constructs textual information about the contents of a bytecode file.
+pprOnDiskModuleByteCode :: OnDiskModuleByteCode -> SDoc
+pprOnDiskModuleByteCode OnDiskModuleByteCode {..}
+ = vcat [
+ pprModuleIdent $ odgbc_module,
+ pprOnDiskModuleByteCodeHash $ odgbc_hash,
+ pprCompiledByteCode odgbc_module $ odgbc_compiled_byte_code
+ ]
+
+-- | Constructs textual information about the name of a module.
+pprModuleIdent :: Module -> SDoc
+pprModuleIdent = entry (text "name") . ppr
+
+-- | Constructs textual information about the hash of a module.
+pprOnDiskModuleByteCodeHash :: Fingerprint -> SDoc
+pprOnDiskModuleByteCodeHash = entry (text "hash") . ppr
+
+-- | Constructs textual information about bytecode.
+pprCompiledByteCode :: Module -- ^ The enclosing module
+ -> CompiledByteCode -- ^ The bytecode
+ -> SDoc -- ^ The textual information
+pprCompiledByteCode currentModule CompiledByteCode {..}
+ = vcat [
+ pprByteCodeObjects currentModule $ bc_bcos,
+ pprDataConstructorInfoTables $ bc_itbls,
+ pprTopLevelStrings $ bc_strs,
+ pprBreakpoints currentModule $ bc_breaks,
+ pprStaticPointerTableEntries $ bc_spt_entries,
+ pprHPCInfo $ bc_hpc_info
+ ]
+
+-- | Constructs textual information about bytecode objects.
+pprByteCodeObjects :: Module -- ^ The enlosing module
+ -> FlatBag UnlinkedBCO -- ^ The bytecode objects
+ -> SDoc -- ^ The textual information
+pprByteCodeObjects currentModule = entry (text "objects") .
+ vcatOrNone .
+ map (pprByteCodeObject currentModule) .
+ elemsFlatBag
+
+-- | Constructs textual information about a single bytecode object.
+pprByteCodeObject :: Module -- ^ The enclosing module
+ -> UnlinkedBCO -- ^ The bytecode object
+ -> SDoc -- ^ The textual information
+pprByteCodeObject currentModule byteCodeObject = case byteCodeObject of
+ UnlinkedBCO {..}
+ -> entry (text "ordinary object" <+> quotes (ppr unlinkedBCOName)) $
+ vcat [
+ pprArity $ unlinkedBCOArity,
+ pprLiterals currentModule $ unlinkedBCOLits,
+ pprPointers currentModule $ unlinkedBCOPtrs
+ ]
+ UnlinkedStaticCon {..}
+ -> entry (
+ text "static-construction object" <+>
+ quotes (ppr unlinkedStaticConName)
+ )
+ $
+ vcat [
+ pprDataConstructorName $ unlinkedStaticConDataConName,
+ pprLiftedness $ not unlinkedStaticConIsUnlifted,
+ pprLiterals currentModule $ unlinkedStaticConLits,
+ pprPointers currentModule $ unlinkedStaticConPtrs
+ ]
+
+-- | Constructs textual information about the arity of an ordinary bytecode
+-- object.
+pprArity :: Int -> SDoc
+pprArity = entry (text "arity") . ppr
+
+-- | Constructs textual information about the data constructor name of a
+-- static-construction bytecode object.
+pprDataConstructorName :: Name -> SDoc
+pprDataConstructorName = entry (text "data constructor name") . ppr
+
+-- | Constructs textual information about the liftedness of a
+-- static-construction bytecode object.
+pprLiftedness :: Bool -> SDoc
+pprLiftedness = entry (text "lifted") . noOrYes
+
+-- | Constructs textual information about literals.
+pprLiterals :: Module -- ^ The enclosing module
+ -> FlatBag BCONPtr -- ^ The literals
+ -> SDoc -- ^ The textual information
+pprLiterals currentModule = entry (text "literals") .
+ vcatOrNone .
+ map (pprLiteral currentModule) .
+ elemsFlatBag
+
+-- | Constructs textual information about a single literal.
+pprLiteral :: Module -- ^ The enclosing module
+ -> BCONPtr -- ^ The literal
+ -> SDoc -- ^ The textual information
+pprLiteral currentModule literal = case literal of
+ BCONPtrWord word
+ -> text "word" <+>
+ ppr word
+ BCONPtrLbl label
+ -> text "label" <+>
+ quotes (ppr label)
+ BCONPtrItbl infoTableName
+ -> text "info table of" <+>
+ quotes (ppr infoTableName)
+ BCONPtrAddr addrName
+ -> text "address" <+>
+ quotes (ppr addrName)
+ BCONPtrStr encodedString
+ -> text "top-level string" <+>
+ text (show (utf8DecodeByteString encodedString))
+ BCONPtrFS string
+ -> text "top-level string" <+>
+ text (show (unpackFS string))
+ BCONPtrFFIInfo ffiInfo
+ -> text "foreign function" <+>
+ quotes (pprFFIInfo ffiInfo)
+ BCONPtrCostCentre breakpointID
+ -> text "cost center of breakpoint" <+>
+ pprInternalBreakpointID currentModule breakpointID
+
+-- | Constructs textual information about FFI info.
+pprFFIInfo :: FFIInfo -> SDoc
+pprFFIInfo FFIInfo {..}
+ = hsep (map (pprFFIType >>> (<+> text "->")) ffiInfoArgs) <+>
+ pprFFIType ffiInfoRet
+
+-- | Constructs textual information about an FFI type.
+pprFFIType :: FFIType -> SDoc
+pprFFIType ffiType = assert (take 3 ident == "FFI") $ text (drop 3 ident) where
+
+ ident :: String
+ ident = show ffiType
+
+-- | Constructs textual information about the ID of a bytecode breakpoint.
+pprInternalBreakpointID
+ :: Module -- ^ The enclosing module
+ -> InternalBreakpointId -- ^ The ID of the bytecode breakpoint
+ -> SDoc -- ^ The textual information
+pprInternalBreakpointID currentModule InternalBreakpointId {..}
+ | ibi_info_mod == currentModule = indexDoc
+ | otherwise = indexDoc <+>
+ text "in" <+>
+ ppr ibi_info_mod
+ where
+
+ indexDoc :: SDoc
+ indexDoc = ppr ibi_info_index
+
+-- | Constructs textual information about pointers.
+pprPointers :: Module -- ^ The enclosing module
+ -> FlatBag BCOPtr -- ^ The pointers
+ -> SDoc -- ^ The textual information
+pprPointers currentModule = entry (text "utilized items") .
+ vcatOrNone .
+ map (pprPointer currentModule) .
+ elemsFlatBag
+
+-- | Constructs textual information about a single pointer.
+pprPointer :: Module -- ^ The enclosing module
+ -> BCOPtr -- ^ The pointer
+ -> SDoc -- ^ The textual information
+pprPointer currentModule pointer = case pointer of
+ BCOPtrName name
+ -> text "item named" <+> quotes (ppr name)
+ BCOPtrPrimOp primOp
+ -> text "primitive operation" <+> quotes (ppr primOp)
+ BCOPtrBCO byteCodeObject
+ -> pprByteCodeObject currentModule byteCodeObject
+ BCOPtrBreakArray breakArrayModule
+ -> text "break array of module" <+> quotes (ppr breakArrayModule)
+
+-- | Constructs textual information about data constructor info tables.
+pprDataConstructorInfoTables :: [(Name, ConInfoTable)] -> SDoc
+pprDataConstructorInfoTables = entry (text "data constructor info tables") .
+ vcatOrNone .
+ map (uncurry pprDataConstructorInfoTable)
+
+-- | Constructs textual information about a single data constructor info table.
+pprDataConstructorInfoTable :: Name -> ConInfoTable -> SDoc
+pprDataConstructorInfoTable dataConstrName ConInfoTable {..}
+ = entry (text "info table of" <+> quotes (ppr dataConstrName)) $
+ vcat [
+ pprPointerWordCount $ conItblPtrs,
+ pprNonPointerWordCount $ conItblNPtrs
+ ]
+
+-- | Constructs textual information about a number of pointer words.
+pprPointerWordCount :: Int -> SDoc
+pprPointerWordCount = entry (text "number of words for pointers") . ppr
+
+-- | Constructs textual information about a number of non-pointer words.
+pprNonPointerWordCount :: Int -> SDoc
+pprNonPointerWordCount = entry (text "number of words for non-pointers") . ppr
+
+-- | Constructs textual information about top-level strings.
+pprTopLevelStrings :: [(Name, ByteString)] -> SDoc
+pprTopLevelStrings = entry (text "top-level strings") .
+ vcatOrNone .
+ map (uncurry pprTopLevelString)
+
+-- | Constructs textual information about a single top-level string.
+pprTopLevelString :: Name -> ByteString -> SDoc
+pprTopLevelString stringName encodedString = entry (ppr stringName) $
+ text $
+ show $
+ utf8DecodeByteString $
+ encodedString
+
+-- | Constructs textual information about breakpoints.
+pprBreakpoints :: Module -- ^ The enclosing module
+ -> Maybe InternalModBreaks -- ^ The breakpoints
+ -> SDoc -- ^ The textual information
+pprBreakpoints currentModule
+ = entry (text "breakpoints") .
+ maybe (text "<none>") (pprActualBreakpoints currentModule)
+
+-- | Constructs textual information about actual breakpoints.
+pprActualBreakpoints :: Module -- ^ The enclosing module
+ -> InternalModBreaks -- ^ The actual breakpoints
+ -> SDoc -- ^ The textual information
+pprActualBreakpoints currentModule InternalModBreaks {..}
+ = vcat [
+ pprSourceBreakpoints currentModule $ imodBreaks_modBreaks,
+ pprByteCodeBreakpoints currentModule $ imodBreaks_breakInfo
+ ]
+
+-- | Constructs textual information about source breakpoints.
+pprSourceBreakpoints :: Module -- ^ The enclosing module
+ -> ModBreaks -- ^ The source breakpoints
+ -> SDoc -- ^ The textual information
+pprSourceBreakpoints currentModule ModBreaks {..}
+ = entry (text "source breakpoints") $
+ assert (modBreaks_module == currentModule) $
+ assert (bounds modBreaks_locs_ == bounds modBreaks_decls) $
+ assert (bounds modBreaks_locs_ == bounds modBreaks_vars) $
+ vcatOrNone $
+ zipWith4 pprSourceBreakpoint (indices modBreaks_locs_)
+ (elems modBreaks_locs_)
+ (elems modBreaks_decls)
+ (elems modBreaks_vars)
+ -- The cost center infos in 'modBreaks_ccs', when present, just contain
+ -- textual representations of the declaration paths in 'modBreaks_decls'
+ -- and the source spans in 'modBreaks_locs_' and are therefore never
+ -- shown.
+
+-- | Constructs textual information about a single source breakpoint.
+pprSourceBreakpoint :: BreakTickIndex
+ -> BinSrcSpan
+ -> [String]
+ -> [OccName]
+ -> SDoc
+pprSourceBreakpoint ix srcSpan declarationPath freeVars
+ = entry (text "source breakpoint" <+> ppr ix) $
+ vcat [
+ pprSrcSpan $ srcSpan,
+ pprDeclarationPath $ declarationPath,
+ pprFreeVariables $ freeVars
+ ]
+
+-- | Constructs textual information about a source span.
+pprSrcSpan :: BinSrcSpan -> SDoc
+pprSrcSpan = entry (text "source span") . ppr . unBinSrcSpan
+
+-- | Constructs textual information about a declaration path.
+pprDeclarationPath :: [String] -> SDoc
+pprDeclarationPath = entry (text "declaration path") . vcatOrEmpty . map text
+
+-- | Constructs textual information about free variables.
+pprFreeVariables :: [OccName] -> SDoc
+pprFreeVariables = entry (text "free variables") . vcatOrNone . map ppr
+
+-- | Constructs textual information about bytecode breakpoints.
+pprByteCodeBreakpoints :: Module -- ^ The enclosing module
+ -> IntMap CgBreakInfo -- ^ The bytecode breakpoints
+ -> SDoc -- ^ The textual information
+pprByteCodeBreakpoints currentModule
+ = entry (text "bytecode breakpoints") .
+ vcatOrNone .
+ map (uncurry (pprByteCodeBreakpoint currentModule)) .
+ IntMap.toList
+
+-- | Constructs textual information about a single bytecode breakpoint.
+pprByteCodeBreakpoint :: Module -- ^ The enclosing module
+ -> Int -- ^ The index of the bytecode breakpoint
+ -> CgBreakInfo -- ^ The bytecode breakpoint
+ -> SDoc -- ^ The textual information
+pprByteCodeBreakpoint currentModule ix CgBreakInfo {..}
+ = entry (text "bytecode breakpoint" <+> ppr ix) $
+ vcat [
+ pprType $ cgb_resty,
+ pprTypeVariables $ cgb_tyvars,
+ pprVariables $ cgb_vars,
+ pprCorrespondingSourceBreakpoint currentModule $ cgb_tick_id
+ ]
+ -- That the 'cgb_resty' field holds the type of the breakpoint is apparent
+ -- from the fact that this field is set by
+ -- 'GHC.StgToByteCode.dehydrateCgBreakInfo' using one of its arguments and
+ -- 'GHC.StgToByteCode.dehydrateCgBreakInfo' is always invoked with this
+ -- argument set to the extension field of 'Breakpoint', which in turn holds
+ -- the type of the breakpoint according to Note [Tickish passes] and the
+ -- comment on the instance declaration of @XBreakpoint 'TickishPassStg@.
+
+-- | Constructs textual information about a type.
+pprType :: IfaceType -> SDoc
+pprType = entry (text "type") . ppr
+
+-- | Constructs textual information about type variables.
+pprTypeVariables :: [IfaceTvBndr] -> SDoc
+pprTypeVariables = entry (text "type variables") .
+ vcatOrNone .
+ map pprTypeVariableBinder
+
+-- | Constructs textual information about a type variable binder.
+pprTypeVariableBinder :: IfaceTvBndr -> SDoc
+pprTypeVariableBinder (name, kind) = ppr name <+> text "::" <+> ppr kind
+
+-- | Constructs textual information about variables.
+pprVariables :: [Maybe (IfaceIdBndr, Word)] -> SDoc
+pprVariables = entry (text "variables") . vcatOrNone . map pprVariable
+
+-- | Constructs textual information about a single variable.
+pprVariable :: Maybe (IfaceIdBndr, Word) -> SDoc
+pprVariable = maybe (text "<unknown>") (pprVariableBinder . fst)
+
+-- | Constructs textual information about a variable binder.
+pprVariableBinder :: IfaceIdBndr -> SDoc
+pprVariableBinder (multiplicity, name, type_)
+ = text "%" <> ppr multiplicity <+>
+ ppr name <+> text "::" <+> ppr type_
+
+-- | Constructs textual information about a source breakpoint corresponding to a
+-- bytecode breakpoint.
+pprCorrespondingSourceBreakpoint :: Module
+ -- ^ The enclosing module
+ -> Either InternalBreakLoc BreakpointId
+ -- ^ A reference to the source breakpoint
+ -> SDoc
+ -- ^ The textual information
+pprCorrespondingSourceBreakpoint currentModule
+ = entry (text "corresponding source breakpoint") .
+ pprBreakpointID currentModule .
+ either internalBreakLoc id
+
+-- | Constructs textual information about the ID of a source breakpoint.
+pprBreakpointID :: Module -- ^ The enclosing module
+ -> BreakpointId -- ^ The ID of the source breakpoint
+ -> SDoc -- ^ The textual information
+pprBreakpointID currentModule BreakpointId {..}
+ | bi_tick_mod == currentModule = indexDoc
+ | otherwise = indexDoc <+>
+ text "in" <+>
+ quotes (ppr bi_tick_mod)
+ where
+
+ indexDoc :: SDoc
+ indexDoc = ppr bi_tick_index
+
+-- | Constructs textual information about static-pointer table entries.
+pprStaticPointerTableEntries :: [SptEntry] -> SDoc
+pprStaticPointerTableEntries = entry (text "static-pointer table entries") .
+ vcatOrNone .
+ map pprStaticPointerTableEntry
+
+-- | Constructs textual information about a single static-pointer table entry.
+pprStaticPointerTableEntry :: SptEntry -> SDoc
+pprStaticPointerTableEntry (SptEntry name fingerprint)
+ = ppr fingerprint <> text ":" <+> ppr name
+
+-- | Constructs textual information about HPC info.
+pprHPCInfo :: Strict.Maybe ByteCodeHpcInfo -> SDoc
+pprHPCInfo = entry (text "HPC information") .
+ Strict.maybe (text "<none>") pprActualHPCInfo
+
+-- | Constructs textual information about actual HPC info.
+pprActualHPCInfo :: ByteCodeHpcInfo -> SDoc
+pprActualHPCInfo ByteCodeHpcInfo {..}
+ = vcat [
+ pprHPCInfoHash $ bchi_hash,
+ pprModuleName $ bchi_module_name,
+ pprTickBoxName $ bchi_tickbox_name,
+ pprTickCount $ bchi_tick_count
+ ]
+ where
+
+-- | Constructs textual information about the hash of HPC info.
+pprHPCInfoHash :: Int -> SDoc
+pprHPCInfoHash = entry (text "hash") . pprFixedSizeNatural
+
+-- | Constructs textual information about a module name.
+pprModuleName :: ShortByteString -> SDoc
+pprModuleName = entry (text "module name") .
+ text .
+ utf8DecodeShortByteString
+
+-- | Constructs textual information about a tick box name.
+pprTickBoxName :: ShortByteString -> SDoc
+pprTickBoxName = entry (text "tick box name") .
+ text .
+ utf8DecodeShortByteString
+
+-- | Constructs textual information about a number of tick counts.
+pprTickCount :: Int -> SDoc
+pprTickCount = entry (text "number of ticks") . ppr
+
+-- | Constructs a hexadecimal representation of a natural number such that the
+-- number of hexadecimal digits fits the number of bits used to represent the
+-- natural number.
+pprFixedSizeNatural :: (Integral a, FiniteBits a) => a -> SDoc
+pprFixedSizeNatural num
+ = assert (num >= 0) $
+ text $ replicate (digitCount - length unpadded) '0' ++ unpadded
+ where
+
+ digitCount :: Int
+ digitCount = (finiteBitSize num + 3) `div` 4
+
+ unpadded :: String
+ unpadded = showHex num ""
+
+-- | Constructs a textual representation of a boolean, interpreting 'True' and
+-- 'False' as “yes” and “no”, respectively.
+noOrYes :: Bool -> SDoc
+noOrYes bool = text (if bool then "yes" else "no")
+
+-- | Constructs an entry in a list of textual data representations.
+entry :: SDoc -- ^ The title of the entry
+ -> SDoc -- ^ The contents of the entry
+ -> SDoc -- ^ The entry
+entry title content = hang (title <> text ":") 2 content
+
+-- | Composes documents vertically in general, but presents an empty document
+-- list as `<none`>.
+vcatOrNone :: [SDoc] -> SDoc
+vcatOrNone [] = text "<none>"
+vcatOrNone docs = vcat docs
+
+-- | Composes documents vertically in general, but presents an empty document
+-- list as `<empty`>.
+vcatOrEmpty :: [SDoc] -> SDoc
+vcatOrEmpty [] = text "<empty>"
+vcatOrEmpty docs = vcat docs
=====================================
compiler/ghc.cabal.in
=====================================
@@ -217,6 +217,7 @@ Library
GHC.ByteCode.Linker
GHC.ByteCode.Recomp.Binary
GHC.ByteCode.Serialize
+ GHC.ByteCode.Show
GHC.ByteCode.Types
GHC.Cmm
GHC.Cmm.BlockId
=====================================
docs/users_guide/using.rst
=====================================
@@ -421,6 +421,13 @@ The available mode flags are:
Read the interface in ⟨file⟩ and dump it as text to ``stdout``. For
example ``ghc --show-iface M.hi``.
+.. ghc-flag:: --show-byte-code ⟨file⟩
+ :shortdesc: display contents of a bytecode file.
+ :type: mode
+ :category: modes
+
+ Read a bytecode file and dump relevant parts of it as text to ``stdout``.
+
.. ghc-flag:: --supported-extensions
--supported-languages
:shortdesc: display the supported language extensions
=====================================
ghc/GHC/Driver/Session/Mode.hs
=====================================
@@ -77,6 +77,7 @@ isShowGhciUsageMode _ = False
data PostLoadMode
= ShowInterface FilePath -- ghc --show-iface
+ | ShowByteCode FilePath -- ghc --show-byte-code
| DoMkDependHS -- ghc -M
| StopBefore StopPhase -- ghc -E | -C | -S
-- StopBefore StopLn is the default
@@ -101,6 +102,9 @@ showUnitsMode = mkPostLoadMode ShowPackages
showInterfaceMode :: FilePath -> Mode
showInterfaceMode fp = mkPostLoadMode (ShowInterface fp)
+showByteCodeMode :: FilePath -> Mode
+showByteCodeMode fp = mkPostLoadMode (ShowByteCode fp)
+
stopBeforeMode :: StopPhase -> Mode
stopBeforeMode phase = mkPostLoadMode (StopBefore phase)
@@ -231,9 +235,11 @@ mode_flags =
replaceSpace ' ' = '-'
replaceSpace c = c
] ++
- ------- interfaces ----------------------------------------------------
- [ defFlag "-show-iface" (HasArg (\f -> setMode (showInterfaceMode f)
+ ------- textual output of generated data -----------------------------
+ [ defFlag "-show-iface" (HasArg (\f -> setMode (showInterfaceMode f)
"--show-iface"))
+ , defFlag "-show-byte-code" (HasArg (\f -> setMode (showByteCodeMode f)
+ "--show-byte-code"))
------- primary modes ------------------------------------------------
, defFlag "c" (PassFlag (\f -> do setMode (stopBeforeMode NoStop) f
=====================================
ghc/Main.hs
=====================================
@@ -73,6 +73,8 @@ import GHC.SysTools.BaseDir
import GHC.Iface.Load
import GHC.Iface.Recomp.Binary ( fingerprintBinMem )
+import GHC.ByteCode.Show ( showByteCode )
+
import GHC.Tc.Utils.Monad ( initIfaceCheck )
import GHC.Iface.Errors.Ppr
@@ -267,6 +269,7 @@ main' postLoadMode units dflags0 args flagWarnings = do
(hsc_units hsc_env)
(hsc_NC hsc_env)
f
+ ShowByteCode f -> liftIO $ showByteCode logger hsc_env f
DoMake -> doMake units srcs
DoMkDependHS -> doMkDependHS (map fst srcs)
StopBefore p -> liftIO (oneShot hsc_env p srcs)
=====================================
testsuite/tests/show-bytecode/Example.hs
=====================================
@@ -0,0 +1,31 @@
+{-# LANGUAGE StaticPointers #-}
+
+module Example where
+
+import Numeric.Natural (Natural)
+import GHC.StaticPtr (StaticPtr)
+
+fibonaccis :: [Natural]
+fibonaccis = 0 : positiveFibonaccis where
+
+ positiveFibonaccis :: [Natural]
+ positiveFibonaccis = 1 : zipWith (+) fibonaccis positiveFibonaccis
+
+fibonaccisPtr :: StaticPtr [Natural]
+fibonaccisPtr = static fibonaccis
+
+divides :: Integral a => a -> a -> Bool
+k `divides` n = n `mod` k == 0
+
+primes :: [Natural]
+primes = 2 : filter isPrime [3 ..] where
+
+ isPrime :: Natural -> Bool
+ isPrime n = not (any (`divides` n) (takeWhile ((<= n) . (^ 2)) primes))
+
+primesPtr :: StaticPtr [Natural]
+primesPtr = static primes
+
+data BinTree a b = Leaf a | Node (BinTree a b) b (BinTree a b)
+
+data PerfectTree a = PerfectTree a | Nested (PerfectTree (a, a))
=====================================
testsuite/tests/show-bytecode/Makefile
=====================================
@@ -0,0 +1,23 @@
+TOP=../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+compile = '$(TEST_HC)' $(TEST_HC_OPTS) -fbyte-code -fwrite-byte-code -no-link
+show = '$(TEST_HC)' $(TEST_HC_OPTS) --show-byte-code
+normalize = sed -E -e ' \
+ s/_r[[:alnum:]]+/_@name_suffix@/g; \
+ s/[[:xdigit:]]{32}/@hash@/g; \
+ s/word [[:digit:]]{4}[[:digit:]]*/word @large_word@/ \
+ '
+
+show-bytecode-vanilla:
+ $(compile) Example.hs
+ $(show) Example.gbc | $(normalize)
+
+show-bytecode-breakpoints:
+ $(compile) -fbreak-points Example.hs
+ $(show) Example.gbc | $(normalize)
+
+show-bytecode-hpc:
+ $(compile) -fhpc Example.hs
+ $(show) Example.gbc | $(normalize)
=====================================
testsuite/tests/show-bytecode/all.T
=====================================
@@ -0,0 +1,18 @@
+test(
+ 'show-bytecode-vanilla',
+ extra_files(['Example.hs']),
+ makefile_test,
+ []
+)
+test(
+ 'show-bytecode-breakpoints',
+ extra_files(['Example.hs']),
+ makefile_test,
+ []
+)
+test(
+ 'show-bytecode-hpc',
+ extra_files(['Example.hs']),
+ makefile_test,
+ []
+)
=====================================
testsuite/tests/show-bytecode/show-bytecode-breakpoints.stdout
=====================================
@@ -0,0 +1,828 @@
+[1 of 1] Compiling Example ( Example.hs, Example.gbc )
+name: Example
+hash: @hash@
+objects:
+ ordinary object ‘primesPtr’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 0
+ utilized items:
+ break array of module ‘Example’
+ item named ‘static_ptr1’
+ item named ‘$dTypeable2_@name_suffix@’
+ item named ‘$fIsStaticStaticPtr’
+ static-construction object ‘static_ptr1’:
+ data constructor name: StaticPtr
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘primes’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: StaticPtrInfo
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "main"
+ utilized items:
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "Example"
+ utilized items:
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: (,)
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 27
+ utilized items: <none>
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 20
+ utilized items: <none>
+ ordinary object ‘primes’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 2
+ info table of ‘:’
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘primes_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 1
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘primes_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘primes_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ word 3
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ item named ‘$fEnumNatural’
+ item named ‘enumFrom’
+ item named ‘isPrime_@name_suffix@’
+ item named ‘filter’
+ ordinary object ‘primes_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ word 2
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ ordinary object ‘isPrime_@name_suffix@’:
+ arity: 1
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 9
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 8
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 7
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 6
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 5
+ word 2
+ info table of ‘IS’
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘v_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$fIntegralInteger’
+ item named ‘$fNumNatural’
+ item named ‘^’
+ ordinary object ‘pap_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: <none>
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 4
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘v_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$fOrdNatural’
+ item named ‘<=’
+ ordinary object ‘pap_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: <none>
+ item named ‘.’
+ item named ‘primes’
+ item named ‘takeWhile’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 3
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘pap_@name_suffix@’:
+ arity: 2
+ literals: <none>
+ utilized items:
+ item named ‘$fIntegralNatural’
+ item named ‘divides’
+ item named ‘$fFoldableList’
+ item named ‘any’
+ item named ‘not’
+ ordinary object ‘fibonaccisPtr’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 10
+ utilized items:
+ break array of module ‘Example’
+ item named ‘static_ptr’
+ item named ‘$dTypeable2_@name_suffix@’
+ item named ‘$fIsStaticStaticPtr’
+ static-construction object ‘static_ptr’:
+ data constructor name: StaticPtr
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘fibonaccis’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: StaticPtrInfo
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "main"
+ utilized items:
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "Example"
+ utilized items:
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: (,)
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 15
+ utilized items: <none>
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 24
+ utilized items: <none>
+ ordinary object ‘fibonaccis’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 11
+ info table of ‘:’
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘fibonaccis_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ word 0
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ item named ‘positiveFibonaccis_@name_suffix@’
+ ordinary object ‘positiveFibonaccis_@name_suffix@’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 13
+ info table of ‘:’
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘positiveFibonaccis_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 12
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘positiveFibonaccis_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘+’
+ item named ‘positiveFibonaccis_@name_suffix@’
+ item named ‘fibonaccis’
+ item named ‘zipWith’
+ ordinary object ‘positiveFibonaccis_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ word 1
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ ordinary object ‘$dTypeable2_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$dTypeable_@name_suffix@’
+ item named ‘$dTypeable1_@name_suffix@’
+ item named ‘mkTrAppChecked’
+ ordinary object ‘$dTypeable1_@name_suffix@’:
+ arity: 0
+ literals: info table of ‘[]’
+ utilized items:
+ item named ‘$tcList’
+ item named ‘mkTrCon’
+ ordinary object ‘$dTypeable_@name_suffix@’:
+ arity: 0
+ literals: info table of ‘[]’
+ utilized items:
+ item named ‘$tcNatural’
+ item named ‘mkTrCon’
+ static-construction object ‘$tc'Nested’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 1
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Nested2_@name_suffix@’
+ item named ‘$krep17_@name_suffix@’
+ static-construction object ‘$tc'Nested2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Nested1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep17_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep16_@name_suffix@’
+ item named ‘$krep13_@name_suffix@’
+ static-construction object ‘$krep16_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcPerfectTree’
+ item named ‘$krep15_@name_suffix@’
+ static-construction object ‘$krep15_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep4_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tc'PerfectTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 1
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'PerfectTree2_@name_suffix@’
+ item named ‘$krep14_@name_suffix@’
+ static-construction object ‘$tc'PerfectTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'PerfectTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep14_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep13_@name_suffix@’
+ static-construction object ‘$krep13_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcPerfectTree’
+ item named ‘$krep12_@name_suffix@’
+ static-construction object ‘$krep12_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tcPerfectTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 0
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tcPerfectTree2_@name_suffix@’
+ item named ‘krep$*Arr*’
+ static-construction object ‘$tcPerfectTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tcPerfectTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$tc'Node’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 2
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Node2_@name_suffix@’
+ item named ‘$krep11_@name_suffix@’
+ static-construction object ‘$tc'Node2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Node1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep11_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep7_@name_suffix@’
+ item named ‘$krep10_@name_suffix@’
+ static-construction object ‘$krep10_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep_@name_suffix@’
+ item named ‘$krep9_@name_suffix@’
+ static-construction object ‘$krep9_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep7_@name_suffix@’
+ item named ‘$krep7_@name_suffix@’
+ static-construction object ‘$tc'Leaf’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 2
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Leaf2_@name_suffix@’
+ item named ‘$krep8_@name_suffix@’
+ static-construction object ‘$tc'Leaf2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Leaf1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep8_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep7_@name_suffix@’
+ static-construction object ‘$krep7_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcBinTree’
+ item named ‘$krep6_@name_suffix@’
+ static-construction object ‘$krep6_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep5_@name_suffix@’
+ static-construction object ‘$krep5_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tcBinTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 0
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tcBinTree2_@name_suffix@’
+ item named ‘krep$*->*->*’
+ static-construction object ‘$tcBinTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tcBinTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep4_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcTuple2’
+ item named ‘$krep3_@name_suffix@’
+ static-construction object ‘$krep3_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep2_@name_suffix@’
+ static-construction object ‘$krep2_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$krep1_@name_suffix@’:
+ data constructor name: KindRepVar
+ lifted: yes
+ literals: word 0
+ utilized items: <none>
+ static-construction object ‘$krep_@name_suffix@’:
+ data constructor name: KindRepVar
+ lifted: yes
+ literals: word 1
+ utilized items: <none>
+ static-construction object ‘$trModule’:
+ data constructor name: Module
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$trModule2_@name_suffix@’
+ item named ‘$trModule4_@name_suffix@’
+ static-construction object ‘$trModule4_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$trModule3_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$trModule2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$trModule1_@name_suffix@’
+ utilized items: <none>
+ ordinary object ‘divides’:
+ arity: 3
+ literals: <none>
+ utilized items:
+ ordinary object ‘$dReal_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘$dNum_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘$dEq_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘$dEq1_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘bcprep_@name_suffix@’:
+ arity: 5
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 15
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ word 0
+ info table of ‘IS’
+ utilized items: item named ‘fromInteger’
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 3
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 14
+ utilized items:
+ break array of module ‘Example’
+ item named ‘mod’
+ item named ‘==’
+ item named ‘$p1Ord’
+ item named ‘$p2Real’
+ item named ‘$p1Real’
+ item named ‘$p1Integral’
+ ordinary object ‘Node’:
+ arity: 3
+ literals: info table of ‘Node’
+ utilized items: <none>
+ ordinary object ‘Leaf’:
+ arity: 1
+ literals: info table of ‘Leaf’
+ utilized items: <none>
+ ordinary object ‘Nested’:
+ arity: 1
+ literals: info table of ‘Nested’
+ utilized items: <none>
+ ordinary object ‘PerfectTree’:
+ arity: 1
+ literals: info table of ‘PerfectTree’
+ utilized items: <none>
+data constructor info tables:
+ info table of ‘PerfectTree’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Nested’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Leaf’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Node’:
+ number of words for pointers: 3
+ number of words for non-pointers: 0
+top-level strings:
+ $tc'Nested1_@name_suffix@: "'Nested"
+ $tc'PerfectTree1_@name_suffix@: "'PerfectTree"
+ $tcPerfectTree1_@name_suffix@: "PerfectTree"
+ $tc'Node1_@name_suffix@: "'Node"
+ $tc'Leaf1_@name_suffix@: "'Leaf"
+ $tcBinTree1_@name_suffix@: "BinTree"
+ $trModule3_@name_suffix@: "Example"
+ $trModule1_@name_suffix@: "main"
+breakpoints:
+ source breakpoints:
+ source breakpoint 0:
+ source span: Example.hs:18:17-25
+ declaration path: divides
+ free variables:
+ k
+ n
+ source breakpoint 1:
+ source span: Example.hs:18:17-30
+ declaration path: divides
+ free variables:
+ k
+ n
+ source breakpoint 2:
+ source span: Example.hs:24:27-37
+ declaration path:
+ primes
+ isPrime
+ free variables: n
+ source breakpoint 3:
+ source span: Example.hs:24:53-56
+ declaration path:
+ primes
+ isPrime
+ free variables: n
+ source breakpoint 4:
+ source span: Example.hs:24:62-64
+ declaration path:
+ primes
+ isPrime
+ free variables: <none>
+ source breakpoint 5:
+ source span: Example.hs:24:52-65
+ declaration path:
+ primes
+ isPrime
+ free variables: n
+ source breakpoint 6:
+ source span: Example.hs:24:41-73
+ declaration path:
+ primes
+ isPrime
+ free variables: n
+ source breakpoint 7:
+ source span: Example.hs:24:22-74
+ declaration path:
+ primes
+ isPrime
+ free variables: n
+ source breakpoint 8:
+ source span: Example.hs:24:17-75
+ declaration path:
+ primes
+ isPrime
+ free variables: n
+ source breakpoint 9:
+ source span: Example.hs:21:14-34
+ declaration path: primes
+ free variables: isPrime
+ source breakpoint 10:
+ source span: Example.hs:21:10-34
+ declaration path: primes
+ free variables: isPrime
+ source breakpoint 11:
+ source span: Example.hs:27:13-25
+ declaration path: primesPtr
+ free variables: <none>
+ source breakpoint 12:
+ source span: Example.hs:12:30-70
+ declaration path:
+ fibonaccis
+ positiveFibonaccis
+ free variables: positiveFibonaccis
+ source breakpoint 13:
+ source span: Example.hs:12:26-70
+ declaration path:
+ fibonaccis
+ positiveFibonaccis
+ free variables: positiveFibonaccis
+ source breakpoint 14:
+ source span: Example.hs:9:14-35
+ declaration path: fibonaccis
+ free variables: positiveFibonaccis
+ source breakpoint 15:
+ source span: Example.hs:15:17-33
+ declaration path: fibonaccisPtr
+ free variables: <none>
+ bytecode breakpoints:
+ bytecode breakpoint 0:
+ type: StaticPtr [Natural]
+ type variables: <none>
+ variables: <none>
+ corresponding source breakpoint: 11
+ bytecode breakpoint 1:
+ type: [Natural]
+ type variables: <none>
+ variables: <unknown>
+ corresponding source breakpoint: 9
+ bytecode breakpoint 2:
+ type: [Natural]
+ type variables: <none>
+ variables: <unknown>
+ corresponding source breakpoint: 10
+ bytecode breakpoint 3:
+ type: Natural -> Bool
+ type variables: <none>
+ variables: %'Many n :: Natural
+ corresponding source breakpoint: 2
+ bytecode breakpoint 4:
+ type: Natural -> Bool
+ type variables: <none>
+ variables: %'Many n :: Natural
+ corresponding source breakpoint: 3
+ bytecode breakpoint 5:
+ type: Natural -> Natural
+ type variables: <none>
+ variables: <none>
+ corresponding source breakpoint: 4
+ bytecode breakpoint 6:
+ type: Natural -> Bool
+ type variables: <none>
+ variables: %'Many n :: Natural
+ corresponding source breakpoint: 5
+ bytecode breakpoint 7:
+ type: [Natural]
+ type variables: <none>
+ variables: %'Many n :: Natural
+ corresponding source breakpoint: 6
+ bytecode breakpoint 8:
+ type: Bool
+ type variables: <none>
+ variables: %'Many n :: Natural
+ corresponding source breakpoint: 7
+ bytecode breakpoint 9:
+ type: Bool
+ type variables: <none>
+ variables: %'Many n :: Natural
+ corresponding source breakpoint: 8
+ bytecode breakpoint 10:
+ type: StaticPtr [Natural]
+ type variables: <none>
+ variables: <none>
+ corresponding source breakpoint: 15
+ bytecode breakpoint 11:
+ type: [Natural]
+ type variables: <none>
+ variables: <unknown>
+ corresponding source breakpoint: 14
+ bytecode breakpoint 12:
+ type: [Natural]
+ type variables: <none>
+ variables: <unknown>
+ corresponding source breakpoint: 12
+ bytecode breakpoint 13:
+ type: [Natural]
+ type variables: <none>
+ variables: <unknown>
+ corresponding source breakpoint: 13
+ bytecode breakpoint 14:
+ type: a
+ type variables: a :: *
+ variables:
+ %'Many eta :: a
+ %'Many eta1 :: a
+ corresponding source breakpoint: 0
+ bytecode breakpoint 15:
+ type: Bool
+ type variables: a :: *
+ variables:
+ %'Many eta :: a
+ %'Many eta1 :: a
+ corresponding source breakpoint: 1
+static-pointer table entries:
+ @hash@: static_ptr
+ @hash@: static_ptr1
+HPC information: <none>
+
=====================================
testsuite/tests/show-bytecode/show-bytecode-hpc.stdout
=====================================
@@ -0,0 +1,668 @@
+[1 of 1] Compiling Example ( Example.hs, Example.gbc )
+name: Example
+hash: @hash@
+objects:
+ ordinary object ‘primesPtr’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ item named ‘static_ptr1’
+ item named ‘$dTypeable2_@name_suffix@’
+ item named ‘$fIsStaticStaticPtr’
+ static-construction object ‘static_ptr1’:
+ data constructor name: StaticPtr
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: StaticPtrInfo
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "main"
+ utilized items:
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "Example"
+ utilized items:
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: (,)
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 27
+ utilized items: <none>
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 20
+ utilized items: <none>
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: item named ‘primes’
+ ordinary object ‘primes2_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘primes2_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘primes2_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ word 3
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ item named ‘$fEnumNatural’
+ item named ‘enumFrom’
+ ordinary object ‘primes2_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: item named ‘isPrime_@name_suffix@’
+ item named ‘filter’
+ ordinary object ‘isPrime_@name_suffix@’:
+ arity: 1
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: item named ‘primes’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘v_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ item named ‘$fIntegralInteger’
+ item named ‘$fNumNatural’
+ item named ‘^’
+ ordinary object ‘v1_@name_suffix@’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ word 2
+ info table of ‘IS’
+ utilized items: <none>
+ ordinary object ‘pap_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: <none>
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘v_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ item named ‘$fOrdNatural’
+ item named ‘<=’
+ ordinary object ‘v1_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: <none>
+ ordinary object ‘pap_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: <none>
+ item named ‘.’
+ item named ‘takeWhile’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘v_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘pap_@name_suffix@’:
+ arity: 2
+ literals: <none>
+ utilized items:
+ item named ‘$fIntegralNatural’
+ item named ‘divides’
+ ordinary object ‘v1_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: <none>
+ ordinary object ‘pap_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: <none>
+ item named ‘$fFoldableList’
+ item named ‘any’
+ item named ‘not’
+ ordinary object ‘primes’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ label ‘_hpc_tickboxes_Example_hpc’
+ info table of ‘:’
+ utilized items:
+ item named ‘primes2_@name_suffix@’
+ item named ‘primes1_@name_suffix@’
+ ordinary object ‘primes1_@name_suffix@’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ word 2
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ ordinary object ‘fibonaccisPtr’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ item named ‘static_ptr’
+ item named ‘$dTypeable2_@name_suffix@’
+ item named ‘$fIsStaticStaticPtr’
+ static-construction object ‘static_ptr’:
+ data constructor name: StaticPtr
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: StaticPtrInfo
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "main"
+ utilized items:
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "Example"
+ utilized items:
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: (,)
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 15
+ utilized items: <none>
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 24
+ utilized items: <none>
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: item named ‘fibonaccis’
+ ordinary object ‘positiveFibonaccis1_@name_suffix@’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ label ‘_hpc_tickboxes_Example_hpc’
+ info table of ‘:’
+ utilized items:
+ item named ‘positiveFibonaccis2_@name_suffix@’
+ item named ‘positiveFibonaccis_@name_suffix@’
+ ordinary object ‘positiveFibonaccis2_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘positiveFibonaccis2_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: item named ‘positiveFibonaccis1_@name_suffix@’
+ ordinary object ‘positiveFibonaccis2_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: item named ‘fibonaccis’
+ ordinary object ‘positiveFibonaccis2_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘+’
+ item named ‘zipWith’
+ ordinary object ‘fibonaccis’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ label ‘_hpc_tickboxes_Example_hpc’
+ info table of ‘:’
+ utilized items:
+ item named ‘fibonaccis2_@name_suffix@’
+ item named ‘fibonaccis1_@name_suffix@’
+ ordinary object ‘fibonaccis2_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: item named ‘positiveFibonaccis1_@name_suffix@’
+ ordinary object ‘positiveFibonaccis_@name_suffix@’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ word 1
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ ordinary object ‘fibonaccis1_@name_suffix@’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ word 0
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ ordinary object ‘$dTypeable2_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$dTypeable_@name_suffix@’
+ item named ‘$dTypeable1_@name_suffix@’
+ item named ‘mkTrAppChecked’
+ ordinary object ‘$dTypeable1_@name_suffix@’:
+ arity: 0
+ literals: info table of ‘[]’
+ utilized items:
+ item named ‘$tcList’
+ item named ‘mkTrCon’
+ ordinary object ‘$dTypeable_@name_suffix@’:
+ arity: 0
+ literals: info table of ‘[]’
+ utilized items:
+ item named ‘$tcNatural’
+ item named ‘mkTrCon’
+ static-construction object ‘$tc'Nested’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 1
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Nested2_@name_suffix@’
+ item named ‘$krep17_@name_suffix@’
+ static-construction object ‘$tc'Nested2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Nested1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep17_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep16_@name_suffix@’
+ item named ‘$krep13_@name_suffix@’
+ static-construction object ‘$krep16_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcPerfectTree’
+ item named ‘$krep15_@name_suffix@’
+ static-construction object ‘$krep15_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep4_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tc'PerfectTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 1
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'PerfectTree2_@name_suffix@’
+ item named ‘$krep14_@name_suffix@’
+ static-construction object ‘$tc'PerfectTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'PerfectTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep14_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep13_@name_suffix@’
+ static-construction object ‘$krep13_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcPerfectTree’
+ item named ‘$krep12_@name_suffix@’
+ static-construction object ‘$krep12_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tcPerfectTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 0
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tcPerfectTree2_@name_suffix@’
+ item named ‘krep$*Arr*’
+ static-construction object ‘$tcPerfectTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tcPerfectTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$tc'Node’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 2
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Node2_@name_suffix@’
+ item named ‘$krep11_@name_suffix@’
+ static-construction object ‘$tc'Node2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Node1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep11_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep7_@name_suffix@’
+ item named ‘$krep10_@name_suffix@’
+ static-construction object ‘$krep10_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep_@name_suffix@’
+ item named ‘$krep9_@name_suffix@’
+ static-construction object ‘$krep9_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep7_@name_suffix@’
+ item named ‘$krep7_@name_suffix@’
+ static-construction object ‘$tc'Leaf’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 2
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Leaf2_@name_suffix@’
+ item named ‘$krep8_@name_suffix@’
+ static-construction object ‘$tc'Leaf2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Leaf1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep8_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep7_@name_suffix@’
+ static-construction object ‘$krep7_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcBinTree’
+ item named ‘$krep6_@name_suffix@’
+ static-construction object ‘$krep6_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep5_@name_suffix@’
+ static-construction object ‘$krep5_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tcBinTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 0
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tcBinTree2_@name_suffix@’
+ item named ‘krep$*->*->*’
+ static-construction object ‘$tcBinTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tcBinTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep4_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcTuple2’
+ item named ‘$krep3_@name_suffix@’
+ static-construction object ‘$krep3_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep2_@name_suffix@’
+ static-construction object ‘$krep2_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$krep1_@name_suffix@’:
+ data constructor name: KindRepVar
+ lifted: yes
+ literals: word 0
+ utilized items: <none>
+ static-construction object ‘$krep_@name_suffix@’:
+ data constructor name: KindRepVar
+ lifted: yes
+ literals: word 1
+ utilized items: <none>
+ static-construction object ‘$trModule’:
+ data constructor name: Module
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$trModule2_@name_suffix@’
+ item named ‘$trModule4_@name_suffix@’
+ static-construction object ‘$trModule4_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$trModule3_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$trModule2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$trModule1_@name_suffix@’
+ utilized items: <none>
+ ordinary object ‘divides’:
+ arity: 3
+ literals: <none>
+ utilized items:
+ ordinary object ‘$dReal_@name_suffix@’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ word 0
+ info table of ‘IS’
+ utilized items:
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘fromInteger’
+ item named ‘$p1Real’
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 3
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: <none>
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: <none>
+ item named ‘mod’
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘==’
+ item named ‘$p1Ord’
+ item named ‘$p2Real’
+ item named ‘$p1Integral’
+ ordinary object ‘Node’:
+ arity: 3
+ literals: info table of ‘Node’
+ utilized items: <none>
+ ordinary object ‘Leaf’:
+ arity: 1
+ literals: info table of ‘Leaf’
+ utilized items: <none>
+ ordinary object ‘Nested’:
+ arity: 1
+ literals: info table of ‘Nested’
+ utilized items: <none>
+ ordinary object ‘PerfectTree’:
+ arity: 1
+ literals: info table of ‘PerfectTree’
+ utilized items: <none>
+data constructor info tables:
+ info table of ‘PerfectTree’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Nested’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Leaf’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Node’:
+ number of words for pointers: 3
+ number of words for non-pointers: 0
+top-level strings:
+ $tc'Nested1_@name_suffix@: "'Nested"
+ $tc'PerfectTree1_@name_suffix@: "'PerfectTree"
+ $tcPerfectTree1_@name_suffix@: "PerfectTree"
+ $tc'Node1_@name_suffix@: "'Node"
+ $tc'Leaf1_@name_suffix@: "'Leaf"
+ $tcBinTree1_@name_suffix@: "BinTree"
+ $trModule3_@name_suffix@: "Example"
+ $trModule1_@name_suffix@: "main"
+breakpoints: <none>
+static-pointer table entries:
+ @hash@: static_ptr
+ @hash@: static_ptr1
+HPC information:
+ hash: 000000006110204f
+ module name: Example
+ tick box name: _hpc_tickboxes_Example_hpc
+ number of ticks: 45
+
=====================================
testsuite/tests/show-bytecode/show-bytecode-vanilla.stdout
=====================================
@@ -0,0 +1,593 @@
+[1 of 1] Compiling Example ( Example.hs, Example.gbc )
+name: Example
+hash: @hash@
+objects:
+ ordinary object ‘primesPtr’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr1’
+ item named ‘$dTypeable2_@name_suffix@’
+ item named ‘$fIsStaticStaticPtr’
+ static-construction object ‘static_ptr1’:
+ data constructor name: StaticPtr
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘primes’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: StaticPtrInfo
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "main"
+ utilized items:
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "Example"
+ utilized items:
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: (,)
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 27
+ utilized items: <none>
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 20
+ utilized items: <none>
+ ordinary object ‘primes2_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘primes2_sat_@name_suffix@’
+ item named ‘isPrime_@name_suffix@’
+ item named ‘filter’
+ ordinary object ‘isPrime_@name_suffix@’:
+ arity: 1
+ literals: <none>
+ utilized items:
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals: <none>
+ utilized items:
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals: <none>
+ utilized items:
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ word 2
+ info table of ‘IS’
+ utilized items:
+ ordinary object ‘v_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$fIntegralInteger’
+ item named ‘$fNumNatural’
+ item named ‘^’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: <none>
+ ordinary object ‘v_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$fOrdNatural’
+ item named ‘<=’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: <none>
+ item named ‘.’
+ item named ‘primes’
+ item named ‘takeWhile’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 2
+ literals: <none>
+ utilized items:
+ item named ‘$fIntegralNatural’
+ item named ‘divides’
+ item named ‘$fFoldableList’
+ item named ‘any’
+ item named ‘not’
+ static-construction object ‘primes’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘primes1_@name_suffix@’
+ item named ‘primes2_@name_suffix@’
+ ordinary object ‘primes2_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘primes2_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ word 3
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ item named ‘$fEnumNatural’
+ item named ‘enumFrom’
+ ordinary object ‘primes1_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘primes1_sat_@name_suffix@’
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ static-construction object ‘primes1_sat_@name_suffix@’:
+ data constructor name: IS
+ lifted: yes
+ literals: word 2
+ utilized items: <none>
+ ordinary object ‘fibonaccisPtr’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr’
+ item named ‘$dTypeable2_@name_suffix@’
+ item named ‘$fIsStaticStaticPtr’
+ static-construction object ‘static_ptr’:
+ data constructor name: StaticPtr
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘fibonaccis’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: StaticPtrInfo
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "main"
+ utilized items:
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "Example"
+ utilized items:
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: (,)
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 15
+ utilized items: <none>
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 24
+ utilized items: <none>
+ ordinary object ‘positiveFibonaccis2_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘positiveFibonaccis1_@name_suffix@’
+ item named ‘fibonaccis’
+ item named ‘positiveFibonaccis2_sat_@name_suffix@’
+ item named ‘zipWith’
+ static-construction object ‘positiveFibonaccis1_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘positiveFibonaccis_@name_suffix@’
+ item named ‘positiveFibonaccis2_@name_suffix@’
+ static-construction object ‘fibonaccis’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘fibonaccis1_@name_suffix@’
+ item named ‘positiveFibonaccis1_@name_suffix@’
+ ordinary object ‘positiveFibonaccis2_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘+’
+ ordinary object ‘positiveFibonaccis_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘positiveFibonaccis_sat_@name_suffix@’
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ static-construction object ‘positiveFibonaccis_sat_@name_suffix@’:
+ data constructor name: IS
+ lifted: yes
+ literals: word 1
+ utilized items: <none>
+ ordinary object ‘fibonaccis1_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘fibonaccis1_sat_@name_suffix@’
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ static-construction object ‘fibonaccis1_sat_@name_suffix@’:
+ data constructor name: IS
+ lifted: yes
+ literals: word 0
+ utilized items: <none>
+ ordinary object ‘$dTypeable2_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$dTypeable_@name_suffix@’
+ item named ‘$dTypeable1_@name_suffix@’
+ item named ‘mkTrAppChecked’
+ ordinary object ‘$dTypeable1_@name_suffix@’:
+ arity: 0
+ literals: info table of ‘[]’
+ utilized items:
+ item named ‘$tcList’
+ item named ‘mkTrCon’
+ ordinary object ‘$dTypeable_@name_suffix@’:
+ arity: 0
+ literals: info table of ‘[]’
+ utilized items:
+ item named ‘$tcNatural’
+ item named ‘mkTrCon’
+ static-construction object ‘$tc'Nested’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 1
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Nested2_@name_suffix@’
+ item named ‘$krep17_@name_suffix@’
+ static-construction object ‘$tc'Nested2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Nested1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep17_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep16_@name_suffix@’
+ item named ‘$krep13_@name_suffix@’
+ static-construction object ‘$krep16_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcPerfectTree’
+ item named ‘$krep15_@name_suffix@’
+ static-construction object ‘$krep15_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep4_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tc'PerfectTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 1
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'PerfectTree2_@name_suffix@’
+ item named ‘$krep14_@name_suffix@’
+ static-construction object ‘$tc'PerfectTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'PerfectTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep14_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep13_@name_suffix@’
+ static-construction object ‘$krep13_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcPerfectTree’
+ item named ‘$krep12_@name_suffix@’
+ static-construction object ‘$krep12_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tcPerfectTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 0
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tcPerfectTree2_@name_suffix@’
+ item named ‘krep$*Arr*’
+ static-construction object ‘$tcPerfectTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tcPerfectTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$tc'Node’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 2
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Node2_@name_suffix@’
+ item named ‘$krep11_@name_suffix@’
+ static-construction object ‘$tc'Node2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Node1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep11_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep7_@name_suffix@’
+ item named ‘$krep10_@name_suffix@’
+ static-construction object ‘$krep10_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep_@name_suffix@’
+ item named ‘$krep9_@name_suffix@’
+ static-construction object ‘$krep9_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep7_@name_suffix@’
+ item named ‘$krep7_@name_suffix@’
+ static-construction object ‘$tc'Leaf’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 2
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Leaf2_@name_suffix@’
+ item named ‘$krep8_@name_suffix@’
+ static-construction object ‘$tc'Leaf2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Leaf1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep8_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep7_@name_suffix@’
+ static-construction object ‘$krep7_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcBinTree’
+ item named ‘$krep6_@name_suffix@’
+ static-construction object ‘$krep6_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep5_@name_suffix@’
+ static-construction object ‘$krep5_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tcBinTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 0
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tcBinTree2_@name_suffix@’
+ item named ‘krep$*->*->*’
+ static-construction object ‘$tcBinTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tcBinTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep4_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcTuple2’
+ item named ‘$krep3_@name_suffix@’
+ static-construction object ‘$krep3_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep2_@name_suffix@’
+ static-construction object ‘$krep2_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$krep1_@name_suffix@’:
+ data constructor name: KindRepVar
+ lifted: yes
+ literals: word 0
+ utilized items: <none>
+ static-construction object ‘$krep_@name_suffix@’:
+ data constructor name: KindRepVar
+ lifted: yes
+ literals: word 1
+ utilized items: <none>
+ static-construction object ‘$trModule’:
+ data constructor name: Module
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$trModule2_@name_suffix@’
+ item named ‘$trModule4_@name_suffix@’
+ static-construction object ‘$trModule4_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$trModule3_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$trModule2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$trModule1_@name_suffix@’
+ utilized items: <none>
+ ordinary object ‘divides’:
+ arity: 3
+ literals: <none>
+ utilized items:
+ ordinary object ‘$dReal_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ word 0
+ info table of ‘IS’
+ utilized items:
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘fromInteger’
+ item named ‘$p1Real’
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: item named ‘mod’
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘==’
+ item named ‘$p1Ord’
+ item named ‘$p2Real’
+ item named ‘$p1Integral’
+ ordinary object ‘Node’:
+ arity: 3
+ literals: info table of ‘Node’
+ utilized items: <none>
+ ordinary object ‘Leaf’:
+ arity: 1
+ literals: info table of ‘Leaf’
+ utilized items: <none>
+ ordinary object ‘Nested’:
+ arity: 1
+ literals: info table of ‘Nested’
+ utilized items: <none>
+ ordinary object ‘PerfectTree’:
+ arity: 1
+ literals: info table of ‘PerfectTree’
+ utilized items: <none>
+data constructor info tables:
+ info table of ‘PerfectTree’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Nested’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Leaf’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Node’:
+ number of words for pointers: 3
+ number of words for non-pointers: 0
+top-level strings:
+ $tc'Nested1_@name_suffix@: "'Nested"
+ $tc'PerfectTree1_@name_suffix@: "'PerfectTree"
+ $tcPerfectTree1_@name_suffix@: "PerfectTree"
+ $tc'Node1_@name_suffix@: "'Node"
+ $tc'Leaf1_@name_suffix@: "'Leaf"
+ $tcBinTree1_@name_suffix@: "BinTree"
+ $trModule3_@name_suffix@: "Example"
+ $trModule1_@name_suffix@: "main"
+breakpoints: <none>
+static-pointer table entries:
+ @hash@: static_ptr
+ @hash@: static_ptr1
+HPC information: <none>
+
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c72054cdccf9c62cfb2b4df96239f63…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/c72054cdccf9c62cfb2b4df96239f63…
You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
1
0
[Git][ghc/ghc][wip/jeltsch/textual-bytecode-output] Add support for textual output of bytecode file contents
by Wolfgang Jeltsch (@jeltsch) 21 Jul '26
by Wolfgang Jeltsch (@jeltsch) 21 Jul '26
21 Jul '26
Wolfgang Jeltsch pushed to branch wip/jeltsch/textual-bytecode-output at Glasgow Haskell Compiler / GHC
Commits:
97ab9bcd by Wolfgang Jeltsch at 2026-07-21T17:11:08+03:00
Add support for textual output of bytecode file contents
This resolves #26909.
- - - - -
12 changed files:
- compiler/GHC/ByteCode/Serialize.hs
- + compiler/GHC/ByteCode/Show.hs
- compiler/ghc.cabal.in
- docs/users_guide/using.rst
- ghc/GHC/Driver/Session/Mode.hs
- ghc/Main.hs
- + testsuite/tests/show-bytecode/Example.hs
- + testsuite/tests/show-bytecode/Makefile
- + testsuite/tests/show-bytecode/all.T
- + testsuite/tests/show-bytecode/show-bytecode-breakpoints.stdout
- + testsuite/tests/show-bytecode/show-bytecode-hpc.stdout
- + testsuite/tests/show-bytecode/show-bytecode-vanilla.stdout
Changes:
=====================================
compiler/GHC/ByteCode/Serialize.hs
=====================================
@@ -6,7 +6,7 @@
{- | This module implements the serialization of bytecode objects to and from disk.
-}
module GHC.ByteCode.Serialize
- ( writeBinByteCode, readBinByteCode
+ ( writeBinByteCode, readBinByteCode, readOnDiskModuleByteCode
, ModuleByteCode(..)
, BytecodeLibX(..)
, BytecodeLib
=====================================
compiler/GHC/ByteCode/Show.hs
=====================================
@@ -0,0 +1,531 @@
+{-# LANGUAGE ImportQualifiedPost #-}
+{-# LANGUAGE RecordWildCards #-}
+
+-- | This module implements the output of textual information about the contents
+-- of bytecode files. It is the backbone of the @--show-byte-code@ option.
+module GHC.ByteCode.Show (showByteCode) where
+
+import Prelude ((+), (-), Integral, div)
+import Control.Arrow ((>>>))
+import Control.Exception (assert)
+import Data.Eq ((==))
+import Data.Ord ((>=))
+import Data.Bits (FiniteBits, finiteBitSize)
+import Data.Function (($), id, (.))
+import Data.Tuple (fst, uncurry)
+import Data.Bool (Bool, otherwise, not)
+import Data.Int (Int)
+import Data.Word (Word)
+import Data.Maybe (Maybe, maybe)
+import Data.Either (Either, either)
+import Data.List (length, (++), map, zipWith4, take, drop, replicate)
+import Data.String (String)
+import Data.ByteString (ByteString)
+import Data.ByteString.Short (ShortByteString)
+import Data.IntMap (IntMap)
+import Data.IntMap qualified as IntMap (toList)
+import Data.Array (bounds, indices, elems)
+import Numeric (showHex)
+import Text.Show (show)
+import System.IO (IO, FilePath)
+import GHC.Data.Strict qualified as Strict (Maybe, maybe)
+import GHC.Data.FastString (unpackFS)
+import GHC.Data.FlatBag (FlatBag, elemsFlatBag)
+import GHC.Fingerprint (Fingerprint)
+import GHC.Types.SrcLoc (noSrcSpan)
+import GHC.Types.Name (Name)
+import GHC.Types.Name.Occurrence (OccName)
+import GHC.Types.Tickish (BreakTickIndex, BreakpointId (..))
+import GHC.Types.SptEntry (SptEntry (..))
+import GHC.Types.Error (MessageClass (MCDump))
+import GHC.Utils.Logger (Logger, logMsg)
+import GHC.Utils.Binary (BinSrcSpan (..))
+import GHC.Utils.Encoding.UTF8 (utf8DecodeShortByteString, utf8DecodeByteString)
+import GHC.Utils.Outputable
+ (
+ defaultDumpStyle,
+ SDoc,
+ text,
+ (<>),
+ (<+>),
+ quotes,
+ hsep,
+ vcat,
+ hang,
+ withPprStyle,
+ ppr
+ )
+import GHC.Unit.Types (Module)
+import GHC.Iface.Type (IfaceType, IfaceTvBndr, IfaceIdBndr)
+import GHC.HsToCore.Breakpoints (ModBreaks (..))
+import GHC.ByteCode.Types
+ (
+ FFIInfo (..),
+ BCONPtr (..),
+ BCOPtr (..),
+ UnlinkedBCO (..),
+ ByteCodeHpcInfo (..),
+ CompiledByteCode (..)
+ )
+import GHC.ByteCode.Breakpoints
+ (
+ InternalBreakpointId (..),
+ InternalBreakLoc (..),
+ CgBreakInfo (..),
+ InternalModBreaks (..)
+ )
+import GHC.ByteCode.Binary (OnDiskModuleByteCode (..))
+import GHC.ByteCode.Serialize (readOnDiskModuleByteCode)
+import GHC.Driver.Env.Types (HscEnv)
+import GHCi.FFI (FFIType)
+import GHCi.Message (ConInfoTable (..))
+
+-- | Outputs textual information about the contents of a bytecode file.
+showByteCode :: Logger -> HscEnv -> FilePath -> IO ()
+showByteCode logger env path = do
+ byteCode <- readOnDiskModuleByteCode env path
+ logMsg logger
+ MCDump
+ noSrcSpan
+ (withPprStyle defaultDumpStyle $ pprOnDiskModuleByteCode byteCode)
+
+-- | Constructs textual information about the contents of a bytecode file.
+pprOnDiskModuleByteCode :: OnDiskModuleByteCode -> SDoc
+pprOnDiskModuleByteCode OnDiskModuleByteCode {..}
+ = vcat [
+ pprModuleIdent $ odgbc_module,
+ pprOnDiskModuleByteCodeHash $ odgbc_hash,
+ pprCompiledByteCode odgbc_module $ odgbc_compiled_byte_code
+ ]
+
+-- | Constructs textual information about the name of a module.
+pprModuleIdent :: Module -> SDoc
+pprModuleIdent = entry (text "name") . ppr
+
+-- | Constructs textual information about the hash of a module.
+pprOnDiskModuleByteCodeHash :: Fingerprint -> SDoc
+pprOnDiskModuleByteCodeHash = entry (text "hash") . ppr
+
+-- | Constructs textual information about bytecode.
+pprCompiledByteCode :: Module -- ^ The enclosing module
+ -> CompiledByteCode -- ^ The bytecode
+ -> SDoc -- ^ The textual information
+pprCompiledByteCode currentModule CompiledByteCode {..}
+ = vcat [
+ pprByteCodeObjects currentModule $ bc_bcos,
+ pprDataConstructorInfoTables $ bc_itbls,
+ pprTopLevelStrings $ bc_strs,
+ pprBreakpoints currentModule $ bc_breaks,
+ pprStaticPointerTableEntries $ bc_spt_entries,
+ pprHPCInfo $ bc_hpc_info
+ ]
+
+-- | Constructs textual information about bytecode objects.
+pprByteCodeObjects :: Module -- ^ The enlosing module
+ -> FlatBag UnlinkedBCO -- ^ The bytecode objects
+ -> SDoc -- ^ The textual information
+pprByteCodeObjects currentModule = entry (text "objects") .
+ vcatOrNone .
+ map (pprByteCodeObject currentModule) .
+ elemsFlatBag
+
+-- | Constructs textual information about a single bytecode object.
+pprByteCodeObject :: Module -- ^ The enclosing module
+ -> UnlinkedBCO -- ^ The bytecode object
+ -> SDoc -- ^ The textual information
+pprByteCodeObject currentModule byteCodeObject = case byteCodeObject of
+ UnlinkedBCO {..}
+ -> entry (text "ordinary object" <+> quotes (ppr unlinkedBCOName)) $
+ vcat [
+ pprArity $ unlinkedBCOArity,
+ pprLiterals currentModule $ unlinkedBCOLits,
+ pprPointers currentModule $ unlinkedBCOPtrs
+ ]
+ UnlinkedStaticCon {..}
+ -> entry (
+ text "static-construction object" <+>
+ quotes (ppr unlinkedStaticConName)
+ )
+ $
+ vcat [
+ pprDataConstructorName $ unlinkedStaticConDataConName,
+ pprLiftedness $ not unlinkedStaticConIsUnlifted,
+ pprLiterals currentModule $ unlinkedStaticConLits,
+ pprPointers currentModule $ unlinkedStaticConPtrs
+ ]
+
+-- | Constructs textual information about the arity of an ordinary bytecode
+-- object.
+pprArity :: Int -> SDoc
+pprArity = entry (text "arity") . ppr
+
+-- | Constructs textual information about the data constructor name of a
+-- static-construction bytecode object.
+pprDataConstructorName :: Name -> SDoc
+pprDataConstructorName = entry (text "data constructor name") . ppr
+
+-- | Constructs textual information about the liftedness of a
+-- static-construction bytecode object.
+pprLiftedness :: Bool -> SDoc
+pprLiftedness = entry (text "lifted") . noOrYes
+
+-- | Constructs textual information about literals.
+pprLiterals :: Module -- ^ The enclosing module
+ -> FlatBag BCONPtr -- ^ The literals
+ -> SDoc -- ^ The textual information
+pprLiterals currentModule = entry (text "literals") .
+ vcatOrNone .
+ map (pprLiteral currentModule) .
+ elemsFlatBag
+
+-- | Constructs textual information about a single literal.
+pprLiteral :: Module -- ^ The enclosing module
+ -> BCONPtr -- ^ The literal
+ -> SDoc -- ^ The textual information
+pprLiteral currentModule literal = case literal of
+ BCONPtrWord word
+ -> text "word" <+>
+ ppr word
+ BCONPtrLbl label
+ -> text "label" <+>
+ quotes (ppr label)
+ BCONPtrItbl infoTableName
+ -> text "info table of" <+>
+ quotes (ppr infoTableName)
+ BCONPtrAddr addrName
+ -> text "address" <+>
+ quotes (ppr addrName)
+ BCONPtrStr encodedString
+ -> text "top-level string" <+>
+ text (show (utf8DecodeByteString encodedString))
+ BCONPtrFS string
+ -> text "top-level string" <+>
+ text (show (unpackFS string))
+ BCONPtrFFIInfo ffiInfo
+ -> text "foreign function" <+>
+ quotes (pprFFIInfo ffiInfo)
+ BCONPtrCostCentre breakpointID
+ -> text "cost center of breakpoint" <+>
+ pprInternalBreakpointID currentModule breakpointID
+
+-- | Constructs textual information about FFI info.
+pprFFIInfo :: FFIInfo -> SDoc
+pprFFIInfo FFIInfo {..}
+ = hsep (map (pprFFIType >>> (<+> text "->")) ffiInfoArgs) <+>
+ pprFFIType ffiInfoRet
+
+-- | Constructs textual information about an FFI type.
+pprFFIType :: FFIType -> SDoc
+pprFFIType ffiType = assert (take 3 ident == "FFI") $ text (drop 3 ident) where
+
+ ident :: String
+ ident = show ffiType
+
+-- | Constructs textual information about the ID of a bytecode breakpoint.
+pprInternalBreakpointID
+ :: Module -- ^ The enclosing module
+ -> InternalBreakpointId -- ^ The ID of the bytecode breakpoint
+ -> SDoc -- ^ The textual information
+pprInternalBreakpointID currentModule InternalBreakpointId {..}
+ | ibi_info_mod == currentModule = indexDoc
+ | otherwise = indexDoc <+>
+ text "in" <+>
+ ppr ibi_info_mod
+ where
+
+ indexDoc :: SDoc
+ indexDoc = ppr ibi_info_index
+
+-- | Constructs textual information about pointers.
+pprPointers :: Module -- ^ The enclosing module
+ -> FlatBag BCOPtr -- ^ The pointers
+ -> SDoc -- ^ The textual information
+pprPointers currentModule = entry (text "utilized items") .
+ vcatOrNone .
+ map (pprPointer currentModule) .
+ elemsFlatBag
+
+-- | Constructs textual information about a single pointer.
+pprPointer :: Module -- ^ The enclosing module
+ -> BCOPtr -- ^ The pointer
+ -> SDoc -- ^ The textual information
+pprPointer currentModule pointer = case pointer of
+ BCOPtrName name
+ -> text "item named" <+> quotes (ppr name)
+ BCOPtrPrimOp primOp
+ -> text "primitive operation" <+> quotes (ppr primOp)
+ BCOPtrBCO byteCodeObject
+ -> pprByteCodeObject currentModule byteCodeObject
+ BCOPtrBreakArray breakArrayModule
+ -> text "break array of module" <+> quotes (ppr breakArrayModule)
+
+-- | Constructs textual information about data constructor info tables.
+pprDataConstructorInfoTables :: [(Name, ConInfoTable)] -> SDoc
+pprDataConstructorInfoTables = entry (text "data constructor info tables") .
+ vcatOrNone .
+ map (uncurry pprDataConstructorInfoTable)
+
+-- | Constructs textual information about a single data constructor info table.
+pprDataConstructorInfoTable :: Name -> ConInfoTable -> SDoc
+pprDataConstructorInfoTable dataConstrName ConInfoTable {..}
+ = entry (text "info table of" <+> quotes (ppr dataConstrName)) $
+ vcat [
+ pprPointerWordCount $ conItblPtrs,
+ pprNonPointerWordCount $ conItblNPtrs
+ ]
+
+-- | Constructs textual information about a number of pointer words.
+pprPointerWordCount :: Int -> SDoc
+pprPointerWordCount = entry (text "number of words for pointers") . ppr
+
+-- | Constructs textual information about a number of non-pointer words.
+pprNonPointerWordCount :: Int -> SDoc
+pprNonPointerWordCount = entry (text "number of words for non-pointers") . ppr
+
+-- | Constructs textual information about top-level strings.
+pprTopLevelStrings :: [(Name, ByteString)] -> SDoc
+pprTopLevelStrings = entry (text "top-level strings") .
+ vcatOrNone .
+ map (uncurry pprTopLevelString)
+
+-- | Constructs textual information about a single top-level string.
+pprTopLevelString :: Name -> ByteString -> SDoc
+pprTopLevelString stringName encodedString = entry (ppr stringName) $
+ text $
+ show $
+ utf8DecodeByteString $
+ encodedString
+
+-- | Constructs textual information about breakpoints.
+pprBreakpoints :: Module -- ^ The enclosing module
+ -> Maybe InternalModBreaks -- ^ The breakpoints
+ -> SDoc -- ^ The textual information
+pprBreakpoints currentModule
+ = entry (text "breakpoints") .
+ maybe (text "<none>") (pprActualBreakpoints currentModule)
+
+-- | Constructs textual information about actual breakpoints.
+pprActualBreakpoints :: Module -- ^ The enclosing module
+ -> InternalModBreaks -- ^ The actual breakpoints
+ -> SDoc -- ^ The textual information
+pprActualBreakpoints currentModule InternalModBreaks {..}
+ = vcat [
+ pprSourceBreakpoints currentModule $ imodBreaks_modBreaks,
+ pprByteCodeBreakpoints currentModule $ imodBreaks_breakInfo
+ ]
+
+-- | Constructs textual information about source breakpoints.
+pprSourceBreakpoints :: Module -- ^ The enclosing module
+ -> ModBreaks -- ^ The source breakpoints
+ -> SDoc -- ^ The textual information
+pprSourceBreakpoints currentModule ModBreaks {..}
+ = entry (text "source breakpoints") $
+ assert (modBreaks_module == currentModule) $
+ assert (bounds modBreaks_locs_ == bounds modBreaks_decls) $
+ assert (bounds modBreaks_locs_ == bounds modBreaks_vars) $
+ vcatOrNone $
+ zipWith4 pprSourceBreakpoint (indices modBreaks_locs_)
+ (elems modBreaks_locs_)
+ (elems modBreaks_decls)
+ (elems modBreaks_vars)
+ -- The cost center infos in 'modBreaks_ccs', when present, just contain
+ -- textual representations of the declaration paths in 'modBreaks_decls'
+ -- and the source spans in 'modBreaks_locs_' and are therefore never
+ -- shown.
+
+-- | Constructs textual information about a single source breakpoint.
+pprSourceBreakpoint :: BreakTickIndex
+ -> BinSrcSpan
+ -> [String]
+ -> [OccName]
+ -> SDoc
+pprSourceBreakpoint ix srcSpan declarationPath freeVars
+ = entry (text "source breakpoint" <+> ppr ix) $
+ vcat [
+ pprSrcSpan $ srcSpan,
+ pprDeclarationPath $ declarationPath,
+ pprFreeVariables $ freeVars
+ ]
+
+-- | Constructs textual information about a source span.
+pprSrcSpan :: BinSrcSpan -> SDoc
+pprSrcSpan = entry (text "source span") . ppr . unBinSrcSpan
+
+-- | Constructs textual information about a declaration path.
+pprDeclarationPath :: [String] -> SDoc
+pprDeclarationPath = entry (text "declaration path") . vcatOrEmpty . map text
+
+-- | Constructs textual information about free variables.
+pprFreeVariables :: [OccName] -> SDoc
+pprFreeVariables = entry (text "free variables") . vcatOrNone . map ppr
+
+-- | Constructs textual information about bytecode breakpoints.
+pprByteCodeBreakpoints :: Module -- ^ The enclosing module
+ -> IntMap CgBreakInfo -- ^ The bytecode breakpoints
+ -> SDoc -- ^ The textual information
+pprByteCodeBreakpoints currentModule
+ = entry (text "bytecode breakpoints") .
+ vcatOrNone .
+ map (uncurry (pprByteCodeBreakpoint currentModule)) .
+ IntMap.toList
+
+-- | Constructs textual information about a single bytecode breakpoint.
+pprByteCodeBreakpoint :: Module -- ^ The enclosing module
+ -> Int -- ^ The index of the bytecode breakpoint
+ -> CgBreakInfo -- ^ The bytecode breakpoint
+ -> SDoc -- ^ The textual information
+pprByteCodeBreakpoint currentModule ix CgBreakInfo {..}
+ = entry (text "bytecode breakpoint" <+> ppr ix) $
+ vcat [
+ pprType $ cgb_resty,
+ pprTypeVariables $ cgb_tyvars,
+ pprVariables $ cgb_vars,
+ pprCorrespondingSourceBreakpoint currentModule $ cgb_tick_id
+ ]
+ -- That the 'cgb_resty' field holds the type of the breakpoint is apparent
+ -- from the fact that this field is set by
+ -- 'GHC.StgToByteCode.dehydrateCgBreakInfo' using one of its arguments and
+ -- 'GHC.StgToByteCode.dehydrateCgBreakInfo' is always invoked with this
+ -- argument set to the extension field of 'Breakpoint', which in turn holds
+ -- the type of the breakpoint according to Note [Tickish passes] and the
+ -- comment on the instance declaration of @XBreakpoint 'TickishPassStg@.
+
+-- | Constructs textual information about a type.
+pprType :: IfaceType -> SDoc
+pprType = entry (text "type") . ppr
+
+-- | Constructs textual information about type variables.
+pprTypeVariables :: [IfaceTvBndr] -> SDoc
+pprTypeVariables = entry (text "type variables") .
+ vcatOrNone .
+ map pprTypeVariableBinder
+
+-- | Constructs textual information about a type variable binder.
+pprTypeVariableBinder :: IfaceTvBndr -> SDoc
+pprTypeVariableBinder (name, kind) = ppr name <+> text "::" <+> ppr kind
+
+-- | Constructs textual information about variables.
+pprVariables :: [Maybe (IfaceIdBndr, Word)] -> SDoc
+pprVariables = entry (text "variables") . vcatOrNone . map pprVariable
+
+-- | Constructs textual information about a single variable.
+pprVariable :: Maybe (IfaceIdBndr, Word) -> SDoc
+pprVariable = maybe (text "<unknown>") (pprVariableBinder . fst)
+
+-- | Constructs textual information about a variable binder.
+pprVariableBinder :: IfaceIdBndr -> SDoc
+pprVariableBinder (multiplicity, name, type_)
+ = text "%" <> ppr multiplicity <+>
+ ppr name <+> text "::" <+> ppr type_
+
+-- | Constructs textual information about a source breakpoint corresponding to a
+-- bytecode breakpoint.
+pprCorrespondingSourceBreakpoint :: Module
+ -- ^ The enclosing module
+ -> Either InternalBreakLoc BreakpointId
+ -- ^ A reference to the source breakpoint
+ -> SDoc
+ -- ^ The textual information
+pprCorrespondingSourceBreakpoint currentModule
+ = entry (text "corresponding source breakpoint") .
+ pprBreakpointID currentModule .
+ either internalBreakLoc id
+
+-- | Constructs textual information about the ID of a source breakpoint.
+pprBreakpointID :: Module -- ^ The enclosing module
+ -> BreakpointId -- ^ The ID of the source breakpoint
+ -> SDoc -- ^ The textual information
+pprBreakpointID currentModule BreakpointId {..}
+ | bi_tick_mod == currentModule = indexDoc
+ | otherwise = indexDoc <+>
+ text "in" <+>
+ quotes (ppr bi_tick_mod)
+ where
+
+ indexDoc :: SDoc
+ indexDoc = ppr bi_tick_index
+
+-- | Constructs textual information about static-pointer table entries.
+pprStaticPointerTableEntries :: [SptEntry] -> SDoc
+pprStaticPointerTableEntries = entry (text "static-pointer table entries") .
+ vcatOrNone .
+ map pprStaticPointerTableEntry
+
+-- | Constructs textual information about a single static-pointer table entry.
+pprStaticPointerTableEntry :: SptEntry -> SDoc
+pprStaticPointerTableEntry (SptEntry name fingerprint)
+ = ppr fingerprint <> text ":" <+> ppr name
+
+-- | Constructs textual information about HPC info.
+pprHPCInfo :: Strict.Maybe ByteCodeHpcInfo -> SDoc
+pprHPCInfo = entry (text "HPC information") .
+ Strict.maybe (text "<none>") pprActualHPCInfo
+
+-- | Constructs textual information about actual HPC info.
+pprActualHPCInfo :: ByteCodeHpcInfo -> SDoc
+pprActualHPCInfo ByteCodeHpcInfo {..}
+ = vcat [
+ pprHPCInfoHash $ bchi_hash,
+ pprModuleName $ bchi_module_name,
+ pprTickBoxName $ bchi_tickbox_name,
+ pprTickCount $ bchi_tick_count
+ ]
+ where
+
+-- | Constructs textual information about the hash of HPC info.
+pprHPCInfoHash :: Int -> SDoc
+pprHPCInfoHash = entry (text "hash") . pprFixedSizeNatural
+
+-- | Constructs textual information about a module name.
+pprModuleName :: ShortByteString -> SDoc
+pprModuleName = entry (text "module name") .
+ text .
+ utf8DecodeShortByteString
+
+-- | Constructs textual information about a tick box name.
+pprTickBoxName :: ShortByteString -> SDoc
+pprTickBoxName = entry (text "tick box name") .
+ text .
+ utf8DecodeShortByteString
+
+-- | Constructs textual information about a number of tick counts.
+pprTickCount :: Int -> SDoc
+pprTickCount = entry (text "number of ticks") . ppr
+
+-- | Constructs a hexadecimal representation of a natural number such that the
+-- number of hexadecimal digits fits the number of bits used to represent the
+-- natural number.
+pprFixedSizeNatural :: (Integral a, FiniteBits a) => a -> SDoc
+pprFixedSizeNatural num
+ = assert (num >= 0) $
+ text $ replicate (digitCount - length unpadded) '0' ++ unpadded
+ where
+
+ digitCount :: Int
+ digitCount = (finiteBitSize num + 3) `div` 4
+
+ unpadded :: String
+ unpadded = showHex num ""
+
+-- | Constructs a textual representation of a boolean, interpreting 'True' and
+-- 'False' as “yes” and “no”, respectively.
+noOrYes :: Bool -> SDoc
+noOrYes bool = text (if bool then "yes" else "no")
+
+-- | Constructs an entry in a list of textual data representations.
+entry :: SDoc -- ^ The title of the entry
+ -> SDoc -- ^ The contents of the entry
+ -> SDoc -- ^ The entry
+entry title content = hang (title <> text ":") 2 content
+
+-- | Composes documents vertically in general, but presents an empty document
+-- list as `<none`>.
+vcatOrNone :: [SDoc] -> SDoc
+vcatOrNone [] = text "<none>"
+vcatOrNone docs = vcat docs
+
+-- | Composes documents vertically in general, but presents an empty document
+-- list as `<empty`>.
+vcatOrEmpty :: [SDoc] -> SDoc
+vcatOrEmpty [] = text "<empty>"
+vcatOrEmpty docs = vcat docs
=====================================
compiler/ghc.cabal.in
=====================================
@@ -217,6 +217,7 @@ Library
GHC.ByteCode.Linker
GHC.ByteCode.Recomp.Binary
GHC.ByteCode.Serialize
+ GHC.ByteCode.Show
GHC.ByteCode.Types
GHC.Cmm
GHC.Cmm.BlockId
=====================================
docs/users_guide/using.rst
=====================================
@@ -421,6 +421,13 @@ The available mode flags are:
Read the interface in ⟨file⟩ and dump it as text to ``stdout``. For
example ``ghc --show-iface M.hi``.
+.. ghc-flag:: --show-byte-code ⟨file⟩
+ :shortdesc: display contents of a bytecode file.
+ :type: mode
+ :category: modes
+
+ Read a bytecode file and dump relevant parts of it as text to ``stdout``.
+
.. ghc-flag:: --supported-extensions
--supported-languages
:shortdesc: display the supported language extensions
=====================================
ghc/GHC/Driver/Session/Mode.hs
=====================================
@@ -77,6 +77,7 @@ isShowGhciUsageMode _ = False
data PostLoadMode
= ShowInterface FilePath -- ghc --show-iface
+ | ShowByteCode FilePath -- ghc --show-byte-code
| DoMkDependHS -- ghc -M
| StopBefore StopPhase -- ghc -E | -C | -S
-- StopBefore StopLn is the default
@@ -101,6 +102,9 @@ showUnitsMode = mkPostLoadMode ShowPackages
showInterfaceMode :: FilePath -> Mode
showInterfaceMode fp = mkPostLoadMode (ShowInterface fp)
+showByteCodeMode :: FilePath -> Mode
+showByteCodeMode fp = mkPostLoadMode (ShowByteCode fp)
+
stopBeforeMode :: StopPhase -> Mode
stopBeforeMode phase = mkPostLoadMode (StopBefore phase)
@@ -231,9 +235,11 @@ mode_flags =
replaceSpace ' ' = '-'
replaceSpace c = c
] ++
- ------- interfaces ----------------------------------------------------
- [ defFlag "-show-iface" (HasArg (\f -> setMode (showInterfaceMode f)
+ ------- textual output of generated data -----------------------------
+ [ defFlag "-show-iface" (HasArg (\f -> setMode (showInterfaceMode f)
"--show-iface"))
+ , defFlag "-show-byte-code" (HasArg (\f -> setMode (showByteCodeMode f)
+ "--show-byte-code"))
------- primary modes ------------------------------------------------
, defFlag "c" (PassFlag (\f -> do setMode (stopBeforeMode NoStop) f
=====================================
ghc/Main.hs
=====================================
@@ -73,6 +73,8 @@ import GHC.SysTools.BaseDir
import GHC.Iface.Load
import GHC.Iface.Recomp.Binary ( fingerprintBinMem )
+import GHC.ByteCode.Show ( showByteCode )
+
import GHC.Tc.Utils.Monad ( initIfaceCheck )
import GHC.Iface.Errors.Ppr
@@ -267,6 +269,7 @@ main' postLoadMode units dflags0 args flagWarnings = do
(hsc_units hsc_env)
(hsc_NC hsc_env)
f
+ ShowByteCode f -> liftIO $ showByteCode logger hsc_env f
DoMake -> doMake units srcs
DoMkDependHS -> doMkDependHS (map fst srcs)
StopBefore p -> liftIO (oneShot hsc_env p srcs)
=====================================
testsuite/tests/show-bytecode/Example.hs
=====================================
@@ -0,0 +1,31 @@
+{-# LANGUAGE StaticPointers #-}
+
+module Example where
+
+import Numeric.Natural (Natural)
+import GHC.StaticPtr (StaticPtr)
+
+fibonaccis :: [Natural]
+fibonaccis = 0 : positiveFibonaccis where
+
+ positiveFibonaccis :: [Natural]
+ positiveFibonaccis = 1 : zipWith (+) fibonaccis positiveFibonaccis
+
+fibonaccisPtr :: StaticPtr [Natural]
+fibonaccisPtr = static fibonaccis
+
+divides :: Integral a => a -> a -> Bool
+k `divides` n = n `mod` k == 0
+
+primes :: [Natural]
+primes = 2 : filter isPrime [3 ..] where
+
+ isPrime :: Natural -> Bool
+ isPrime n = not (any (`divides` n) (takeWhile ((<= n) . (^ 2)) primes))
+
+primesPtr :: StaticPtr [Natural]
+primesPtr = static primes
+
+data BinTree a b = Leaf a | Node (BinTree a b) b (BinTree a b)
+
+data PerfectTree a = PerfectTree a | Nested (PerfectTree (a, a))
=====================================
testsuite/tests/show-bytecode/Makefile
=====================================
@@ -0,0 +1,23 @@
+TOP=../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+compile = '$(TEST_HC)' $(TEST_HC_OPTS) -fbyte-code -fwrite-byte-code -no-link
+show = '$(TEST_HC)' $(TEST_HC_OPTS) --show-byte-code
+normalize = sed -E -e ' \
+ s/_r[[:alnum:]]+/_@name_suffix@/g; \
+ s/[[:xdigit:]]{32}/@hash@/g; \
+ s/word [[:digit:]]{4}[[:digit:]]*/word @large_word@/ \
+ '
+
+show-bytecode-vanilla:
+ $(compile) Example.hs
+ $(show) Example.gbc | $(normalize)
+
+show-bytecode-breakpoints:
+ $(compile) -fbreak-points Example.hs
+ $(show) Example.gbc | $(normalize)
+
+show-bytecode-hpc:
+ $(compile) -fhpc Example.hs
+ $(show) Example.gbc | $(normalize)
=====================================
testsuite/tests/show-bytecode/all.T
=====================================
@@ -0,0 +1,18 @@
+test(
+ 'show-bytecode-vanilla',
+ extra_files(['Example.hs']),
+ makefile_test,
+ []
+)
+test(
+ 'show-bytecode-breakpoints',
+ extra_files(['Example.hs']),
+ makefile_test,
+ []
+)
+test(
+ 'show-bytecode-hpc',
+ extra_files(['Example.hs']),
+ makefile_test,
+ []
+)
=====================================
testsuite/tests/show-bytecode/show-bytecode-breakpoints.stdout
=====================================
@@ -0,0 +1,828 @@
+[1 of 1] Compiling Example ( Example.hs, Example.gbc )
+name: Example
+hash: @hash@
+objects:
+ ordinary object ‘primesPtr’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 0
+ utilized items:
+ break array of module ‘Example’
+ item named ‘static_ptr1’
+ item named ‘$dTypeable2_@name_suffix@’
+ item named ‘$fIsStaticStaticPtr’
+ static-construction object ‘static_ptr1’:
+ data constructor name: StaticPtr
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘primes’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: StaticPtrInfo
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "main"
+ utilized items:
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "Example"
+ utilized items:
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: (,)
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 27
+ utilized items: <none>
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 20
+ utilized items: <none>
+ ordinary object ‘primes’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 2
+ info table of ‘:’
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘primes_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 1
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘primes_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘primes_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ word 3
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ item named ‘$fEnumNatural’
+ item named ‘enumFrom’
+ item named ‘isPrime_@name_suffix@’
+ item named ‘filter’
+ ordinary object ‘primes_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ word 2
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ ordinary object ‘isPrime_@name_suffix@’:
+ arity: 1
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 9
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 8
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 7
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 6
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 5
+ word 2
+ info table of ‘IS’
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘v_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$fIntegralInteger’
+ item named ‘$fNumNatural’
+ item named ‘^’
+ ordinary object ‘pap_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: <none>
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 4
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘v_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$fOrdNatural’
+ item named ‘<=’
+ ordinary object ‘pap_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: <none>
+ item named ‘.’
+ item named ‘primes’
+ item named ‘takeWhile’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 3
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘pap_@name_suffix@’:
+ arity: 2
+ literals: <none>
+ utilized items:
+ item named ‘$fIntegralNatural’
+ item named ‘divides’
+ item named ‘$fFoldableList’
+ item named ‘any’
+ item named ‘not’
+ ordinary object ‘fibonaccisPtr’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 10
+ utilized items:
+ break array of module ‘Example’
+ item named ‘static_ptr’
+ item named ‘$dTypeable2_@name_suffix@’
+ item named ‘$fIsStaticStaticPtr’
+ static-construction object ‘static_ptr’:
+ data constructor name: StaticPtr
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘fibonaccis’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: StaticPtrInfo
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "main"
+ utilized items:
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "Example"
+ utilized items:
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: (,)
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 15
+ utilized items: <none>
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 24
+ utilized items: <none>
+ ordinary object ‘fibonaccis’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 11
+ info table of ‘:’
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘fibonaccis_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ word 0
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ item named ‘positiveFibonaccis_@name_suffix@’
+ ordinary object ‘positiveFibonaccis_@name_suffix@’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 13
+ info table of ‘:’
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘positiveFibonaccis_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 12
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘positiveFibonaccis_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘+’
+ item named ‘positiveFibonaccis_@name_suffix@’
+ item named ‘fibonaccis’
+ item named ‘zipWith’
+ ordinary object ‘positiveFibonaccis_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ word 1
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ ordinary object ‘$dTypeable2_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$dTypeable_@name_suffix@’
+ item named ‘$dTypeable1_@name_suffix@’
+ item named ‘mkTrAppChecked’
+ ordinary object ‘$dTypeable1_@name_suffix@’:
+ arity: 0
+ literals: info table of ‘[]’
+ utilized items:
+ item named ‘$tcList’
+ item named ‘mkTrCon’
+ ordinary object ‘$dTypeable_@name_suffix@’:
+ arity: 0
+ literals: info table of ‘[]’
+ utilized items:
+ item named ‘$tcNatural’
+ item named ‘mkTrCon’
+ static-construction object ‘$tc'Nested’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 1
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Nested2_@name_suffix@’
+ item named ‘$krep17_@name_suffix@’
+ static-construction object ‘$tc'Nested2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Nested1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep17_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep16_@name_suffix@’
+ item named ‘$krep13_@name_suffix@’
+ static-construction object ‘$krep16_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcPerfectTree’
+ item named ‘$krep15_@name_suffix@’
+ static-construction object ‘$krep15_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep4_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tc'PerfectTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 1
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'PerfectTree2_@name_suffix@’
+ item named ‘$krep14_@name_suffix@’
+ static-construction object ‘$tc'PerfectTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'PerfectTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep14_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep13_@name_suffix@’
+ static-construction object ‘$krep13_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcPerfectTree’
+ item named ‘$krep12_@name_suffix@’
+ static-construction object ‘$krep12_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tcPerfectTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 0
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tcPerfectTree2_@name_suffix@’
+ item named ‘krep$*Arr*’
+ static-construction object ‘$tcPerfectTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tcPerfectTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$tc'Node’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 2
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Node2_@name_suffix@’
+ item named ‘$krep11_@name_suffix@’
+ static-construction object ‘$tc'Node2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Node1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep11_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep7_@name_suffix@’
+ item named ‘$krep10_@name_suffix@’
+ static-construction object ‘$krep10_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep_@name_suffix@’
+ item named ‘$krep9_@name_suffix@’
+ static-construction object ‘$krep9_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep7_@name_suffix@’
+ item named ‘$krep7_@name_suffix@’
+ static-construction object ‘$tc'Leaf’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 2
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Leaf2_@name_suffix@’
+ item named ‘$krep8_@name_suffix@’
+ static-construction object ‘$tc'Leaf2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Leaf1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep8_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep7_@name_suffix@’
+ static-construction object ‘$krep7_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcBinTree’
+ item named ‘$krep6_@name_suffix@’
+ static-construction object ‘$krep6_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep5_@name_suffix@’
+ static-construction object ‘$krep5_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tcBinTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 0
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tcBinTree2_@name_suffix@’
+ item named ‘krep$*->*->*’
+ static-construction object ‘$tcBinTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tcBinTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep4_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcTuple2’
+ item named ‘$krep3_@name_suffix@’
+ static-construction object ‘$krep3_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep2_@name_suffix@’
+ static-construction object ‘$krep2_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$krep1_@name_suffix@’:
+ data constructor name: KindRepVar
+ lifted: yes
+ literals: word 0
+ utilized items: <none>
+ static-construction object ‘$krep_@name_suffix@’:
+ data constructor name: KindRepVar
+ lifted: yes
+ literals: word 1
+ utilized items: <none>
+ static-construction object ‘$trModule’:
+ data constructor name: Module
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$trModule2_@name_suffix@’
+ item named ‘$trModule4_@name_suffix@’
+ static-construction object ‘$trModule4_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$trModule3_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$trModule2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$trModule1_@name_suffix@’
+ utilized items: <none>
+ ordinary object ‘divides’:
+ arity: 3
+ literals: <none>
+ utilized items:
+ ordinary object ‘$dReal_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘$dNum_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘$dEq_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘$dEq1_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘bcprep_@name_suffix@’:
+ arity: 5
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 15
+ utilized items:
+ break array of module ‘Example’
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ word 0
+ info table of ‘IS’
+ utilized items: item named ‘fromInteger’
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 3
+ literals:
+ top-level string "Example"
+ top-level string "main"
+ cost center of breakpoint 14
+ utilized items:
+ break array of module ‘Example’
+ item named ‘mod’
+ item named ‘==’
+ item named ‘$p1Ord’
+ item named ‘$p2Real’
+ item named ‘$p1Real’
+ item named ‘$p1Integral’
+ ordinary object ‘Node’:
+ arity: 3
+ literals: info table of ‘Node’
+ utilized items: <none>
+ ordinary object ‘Leaf’:
+ arity: 1
+ literals: info table of ‘Leaf’
+ utilized items: <none>
+ ordinary object ‘Nested’:
+ arity: 1
+ literals: info table of ‘Nested’
+ utilized items: <none>
+ ordinary object ‘PerfectTree’:
+ arity: 1
+ literals: info table of ‘PerfectTree’
+ utilized items: <none>
+data constructor info tables:
+ info table of ‘PerfectTree’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Nested’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Leaf’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Node’:
+ number of words for pointers: 3
+ number of words for non-pointers: 0
+top-level strings:
+ $tc'Nested1_@name_suffix@: "'Nested"
+ $tc'PerfectTree1_@name_suffix@: "'PerfectTree"
+ $tcPerfectTree1_@name_suffix@: "PerfectTree"
+ $tc'Node1_@name_suffix@: "'Node"
+ $tc'Leaf1_@name_suffix@: "'Leaf"
+ $tcBinTree1_@name_suffix@: "BinTree"
+ $trModule3_@name_suffix@: "Example"
+ $trModule1_@name_suffix@: "main"
+breakpoints:
+ source breakpoints:
+ source breakpoint 0:
+ source span: Example.hs:18:17-25
+ declaration path: divides
+ free variables:
+ k
+ n
+ source breakpoint 1:
+ source span: Example.hs:18:17-30
+ declaration path: divides
+ free variables:
+ k
+ n
+ source breakpoint 2:
+ source span: Example.hs:24:27-37
+ declaration path:
+ primes
+ isPrime
+ free variables: n
+ source breakpoint 3:
+ source span: Example.hs:24:53-56
+ declaration path:
+ primes
+ isPrime
+ free variables: n
+ source breakpoint 4:
+ source span: Example.hs:24:62-64
+ declaration path:
+ primes
+ isPrime
+ free variables: <none>
+ source breakpoint 5:
+ source span: Example.hs:24:52-65
+ declaration path:
+ primes
+ isPrime
+ free variables: n
+ source breakpoint 6:
+ source span: Example.hs:24:41-73
+ declaration path:
+ primes
+ isPrime
+ free variables: n
+ source breakpoint 7:
+ source span: Example.hs:24:22-74
+ declaration path:
+ primes
+ isPrime
+ free variables: n
+ source breakpoint 8:
+ source span: Example.hs:24:17-75
+ declaration path:
+ primes
+ isPrime
+ free variables: n
+ source breakpoint 9:
+ source span: Example.hs:21:14-34
+ declaration path: primes
+ free variables: isPrime
+ source breakpoint 10:
+ source span: Example.hs:21:10-34
+ declaration path: primes
+ free variables: isPrime
+ source breakpoint 11:
+ source span: Example.hs:27:13-25
+ declaration path: primesPtr
+ free variables: <none>
+ source breakpoint 12:
+ source span: Example.hs:12:30-70
+ declaration path:
+ fibonaccis
+ positiveFibonaccis
+ free variables: positiveFibonaccis
+ source breakpoint 13:
+ source span: Example.hs:12:26-70
+ declaration path:
+ fibonaccis
+ positiveFibonaccis
+ free variables: positiveFibonaccis
+ source breakpoint 14:
+ source span: Example.hs:9:14-35
+ declaration path: fibonaccis
+ free variables: positiveFibonaccis
+ source breakpoint 15:
+ source span: Example.hs:15:17-33
+ declaration path: fibonaccisPtr
+ free variables: <none>
+ bytecode breakpoints:
+ bytecode breakpoint 0:
+ type: StaticPtr [Natural]
+ type variables: <none>
+ variables: <none>
+ corresponding source breakpoint: 11
+ bytecode breakpoint 1:
+ type: [Natural]
+ type variables: <none>
+ variables: <unknown>
+ corresponding source breakpoint: 9
+ bytecode breakpoint 2:
+ type: [Natural]
+ type variables: <none>
+ variables: <unknown>
+ corresponding source breakpoint: 10
+ bytecode breakpoint 3:
+ type: Natural -> Bool
+ type variables: <none>
+ variables: %'Many n :: Natural
+ corresponding source breakpoint: 2
+ bytecode breakpoint 4:
+ type: Natural -> Bool
+ type variables: <none>
+ variables: %'Many n :: Natural
+ corresponding source breakpoint: 3
+ bytecode breakpoint 5:
+ type: Natural -> Natural
+ type variables: <none>
+ variables: <none>
+ corresponding source breakpoint: 4
+ bytecode breakpoint 6:
+ type: Natural -> Bool
+ type variables: <none>
+ variables: %'Many n :: Natural
+ corresponding source breakpoint: 5
+ bytecode breakpoint 7:
+ type: [Natural]
+ type variables: <none>
+ variables: %'Many n :: Natural
+ corresponding source breakpoint: 6
+ bytecode breakpoint 8:
+ type: Bool
+ type variables: <none>
+ variables: %'Many n :: Natural
+ corresponding source breakpoint: 7
+ bytecode breakpoint 9:
+ type: Bool
+ type variables: <none>
+ variables: %'Many n :: Natural
+ corresponding source breakpoint: 8
+ bytecode breakpoint 10:
+ type: StaticPtr [Natural]
+ type variables: <none>
+ variables: <none>
+ corresponding source breakpoint: 15
+ bytecode breakpoint 11:
+ type: [Natural]
+ type variables: <none>
+ variables: <unknown>
+ corresponding source breakpoint: 14
+ bytecode breakpoint 12:
+ type: [Natural]
+ type variables: <none>
+ variables: <unknown>
+ corresponding source breakpoint: 12
+ bytecode breakpoint 13:
+ type: [Natural]
+ type variables: <none>
+ variables: <unknown>
+ corresponding source breakpoint: 13
+ bytecode breakpoint 14:
+ type: a
+ type variables: a :: *
+ variables:
+ %'Many eta :: a
+ %'Many eta1 :: a
+ corresponding source breakpoint: 0
+ bytecode breakpoint 15:
+ type: Bool
+ type variables: a :: *
+ variables:
+ %'Many eta :: a
+ %'Many eta1 :: a
+ corresponding source breakpoint: 1
+static-pointer table entries:
+ @hash@: static_ptr
+ @hash@: static_ptr1
+HPC information: <none>
+
=====================================
testsuite/tests/show-bytecode/show-bytecode-hpc.stdout
=====================================
@@ -0,0 +1,668 @@
+[1 of 1] Compiling Example ( Example.hs, Example.gbc )
+name: Example
+hash: @hash@
+objects:
+ ordinary object ‘primesPtr’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ item named ‘static_ptr1’
+ item named ‘$dTypeable2_@name_suffix@’
+ item named ‘$fIsStaticStaticPtr’
+ static-construction object ‘static_ptr1’:
+ data constructor name: StaticPtr
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: StaticPtrInfo
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "main"
+ utilized items:
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "Example"
+ utilized items:
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: (,)
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 27
+ utilized items: <none>
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 20
+ utilized items: <none>
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: item named ‘primes’
+ ordinary object ‘primes2_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘primes2_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘primes2_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ word 3
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ item named ‘$fEnumNatural’
+ item named ‘enumFrom’
+ ordinary object ‘primes2_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: item named ‘isPrime_@name_suffix@’
+ item named ‘filter’
+ ordinary object ‘isPrime_@name_suffix@’:
+ arity: 1
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: item named ‘primes’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘v_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ item named ‘$fIntegralInteger’
+ item named ‘$fNumNatural’
+ item named ‘^’
+ ordinary object ‘v1_@name_suffix@’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ word 2
+ info table of ‘IS’
+ utilized items: <none>
+ ordinary object ‘pap_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: <none>
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘v_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ item named ‘$fOrdNatural’
+ item named ‘<=’
+ ordinary object ‘v1_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: <none>
+ ordinary object ‘pap_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: <none>
+ item named ‘.’
+ item named ‘takeWhile’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘v_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘pap_@name_suffix@’:
+ arity: 2
+ literals: <none>
+ utilized items:
+ item named ‘$fIntegralNatural’
+ item named ‘divides’
+ ordinary object ‘v1_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: <none>
+ ordinary object ‘pap_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: <none>
+ item named ‘$fFoldableList’
+ item named ‘any’
+ item named ‘not’
+ ordinary object ‘primes’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ label ‘_hpc_tickboxes_Example_hpc’
+ info table of ‘:’
+ utilized items:
+ item named ‘primes2_@name_suffix@’
+ item named ‘primes1_@name_suffix@’
+ ordinary object ‘primes1_@name_suffix@’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ word 2
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ ordinary object ‘fibonaccisPtr’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ item named ‘static_ptr’
+ item named ‘$dTypeable2_@name_suffix@’
+ item named ‘$fIsStaticStaticPtr’
+ static-construction object ‘static_ptr’:
+ data constructor name: StaticPtr
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: StaticPtrInfo
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "main"
+ utilized items:
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "Example"
+ utilized items:
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: (,)
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 15
+ utilized items: <none>
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 24
+ utilized items: <none>
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: item named ‘fibonaccis’
+ ordinary object ‘positiveFibonaccis1_@name_suffix@’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ label ‘_hpc_tickboxes_Example_hpc’
+ info table of ‘:’
+ utilized items:
+ item named ‘positiveFibonaccis2_@name_suffix@’
+ item named ‘positiveFibonaccis_@name_suffix@’
+ ordinary object ‘positiveFibonaccis2_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘positiveFibonaccis2_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: item named ‘positiveFibonaccis1_@name_suffix@’
+ ordinary object ‘positiveFibonaccis2_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: item named ‘fibonaccis’
+ ordinary object ‘positiveFibonaccis2_sat_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘+’
+ item named ‘zipWith’
+ ordinary object ‘fibonaccis’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ label ‘_hpc_tickboxes_Example_hpc’
+ info table of ‘:’
+ utilized items:
+ item named ‘fibonaccis2_@name_suffix@’
+ item named ‘fibonaccis1_@name_suffix@’
+ ordinary object ‘fibonaccis2_@name_suffix@’:
+ arity: 0
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: item named ‘positiveFibonaccis1_@name_suffix@’
+ ordinary object ‘positiveFibonaccis_@name_suffix@’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ word 1
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ ordinary object ‘fibonaccis1_@name_suffix@’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ word 0
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ ordinary object ‘$dTypeable2_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$dTypeable_@name_suffix@’
+ item named ‘$dTypeable1_@name_suffix@’
+ item named ‘mkTrAppChecked’
+ ordinary object ‘$dTypeable1_@name_suffix@’:
+ arity: 0
+ literals: info table of ‘[]’
+ utilized items:
+ item named ‘$tcList’
+ item named ‘mkTrCon’
+ ordinary object ‘$dTypeable_@name_suffix@’:
+ arity: 0
+ literals: info table of ‘[]’
+ utilized items:
+ item named ‘$tcNatural’
+ item named ‘mkTrCon’
+ static-construction object ‘$tc'Nested’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 1
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Nested2_@name_suffix@’
+ item named ‘$krep17_@name_suffix@’
+ static-construction object ‘$tc'Nested2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Nested1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep17_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep16_@name_suffix@’
+ item named ‘$krep13_@name_suffix@’
+ static-construction object ‘$krep16_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcPerfectTree’
+ item named ‘$krep15_@name_suffix@’
+ static-construction object ‘$krep15_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep4_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tc'PerfectTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 1
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'PerfectTree2_@name_suffix@’
+ item named ‘$krep14_@name_suffix@’
+ static-construction object ‘$tc'PerfectTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'PerfectTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep14_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep13_@name_suffix@’
+ static-construction object ‘$krep13_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcPerfectTree’
+ item named ‘$krep12_@name_suffix@’
+ static-construction object ‘$krep12_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tcPerfectTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 0
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tcPerfectTree2_@name_suffix@’
+ item named ‘krep$*Arr*’
+ static-construction object ‘$tcPerfectTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tcPerfectTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$tc'Node’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 2
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Node2_@name_suffix@’
+ item named ‘$krep11_@name_suffix@’
+ static-construction object ‘$tc'Node2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Node1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep11_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep7_@name_suffix@’
+ item named ‘$krep10_@name_suffix@’
+ static-construction object ‘$krep10_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep_@name_suffix@’
+ item named ‘$krep9_@name_suffix@’
+ static-construction object ‘$krep9_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep7_@name_suffix@’
+ item named ‘$krep7_@name_suffix@’
+ static-construction object ‘$tc'Leaf’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 2
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Leaf2_@name_suffix@’
+ item named ‘$krep8_@name_suffix@’
+ static-construction object ‘$tc'Leaf2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Leaf1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep8_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep7_@name_suffix@’
+ static-construction object ‘$krep7_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcBinTree’
+ item named ‘$krep6_@name_suffix@’
+ static-construction object ‘$krep6_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep5_@name_suffix@’
+ static-construction object ‘$krep5_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tcBinTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 0
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tcBinTree2_@name_suffix@’
+ item named ‘krep$*->*->*’
+ static-construction object ‘$tcBinTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tcBinTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep4_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcTuple2’
+ item named ‘$krep3_@name_suffix@’
+ static-construction object ‘$krep3_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep2_@name_suffix@’
+ static-construction object ‘$krep2_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$krep1_@name_suffix@’:
+ data constructor name: KindRepVar
+ lifted: yes
+ literals: word 0
+ utilized items: <none>
+ static-construction object ‘$krep_@name_suffix@’:
+ data constructor name: KindRepVar
+ lifted: yes
+ literals: word 1
+ utilized items: <none>
+ static-construction object ‘$trModule’:
+ data constructor name: Module
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$trModule2_@name_suffix@’
+ item named ‘$trModule4_@name_suffix@’
+ static-construction object ‘$trModule4_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$trModule3_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$trModule2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$trModule1_@name_suffix@’
+ utilized items: <none>
+ ordinary object ‘divides’:
+ arity: 3
+ literals: <none>
+ utilized items:
+ ordinary object ‘$dReal_@name_suffix@’:
+ arity: 0
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ label ‘_hpc_tickboxes_Example_hpc’
+ word 0
+ info table of ‘IS’
+ utilized items:
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘fromInteger’
+ item named ‘$p1Real’
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 3
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items:
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: <none>
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 1
+ literals: label ‘_hpc_tickboxes_Example_hpc’
+ utilized items: <none>
+ item named ‘mod’
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘==’
+ item named ‘$p1Ord’
+ item named ‘$p2Real’
+ item named ‘$p1Integral’
+ ordinary object ‘Node’:
+ arity: 3
+ literals: info table of ‘Node’
+ utilized items: <none>
+ ordinary object ‘Leaf’:
+ arity: 1
+ literals: info table of ‘Leaf’
+ utilized items: <none>
+ ordinary object ‘Nested’:
+ arity: 1
+ literals: info table of ‘Nested’
+ utilized items: <none>
+ ordinary object ‘PerfectTree’:
+ arity: 1
+ literals: info table of ‘PerfectTree’
+ utilized items: <none>
+data constructor info tables:
+ info table of ‘PerfectTree’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Nested’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Leaf’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Node’:
+ number of words for pointers: 3
+ number of words for non-pointers: 0
+top-level strings:
+ $tc'Nested1_@name_suffix@: "'Nested"
+ $tc'PerfectTree1_@name_suffix@: "'PerfectTree"
+ $tcPerfectTree1_@name_suffix@: "PerfectTree"
+ $tc'Node1_@name_suffix@: "'Node"
+ $tc'Leaf1_@name_suffix@: "'Leaf"
+ $tcBinTree1_@name_suffix@: "BinTree"
+ $trModule3_@name_suffix@: "Example"
+ $trModule1_@name_suffix@: "main"
+breakpoints: <none>
+static-pointer table entries:
+ @hash@: static_ptr
+ @hash@: static_ptr1
+HPC information:
+ hash: 000000006110204f
+ module name: Example
+ tick box name: _hpc_tickboxes_Example_hpc
+ number of ticks: 45
+
=====================================
testsuite/tests/show-bytecode/show-bytecode-vanilla.stdout
=====================================
@@ -0,0 +1,593 @@
+[1 of 1] Compiling Example ( Example.hs, Example.gbc )
+name: Example
+hash: @hash@
+objects:
+ ordinary object ‘primesPtr’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr1’
+ item named ‘$dTypeable2_@name_suffix@’
+ item named ‘$fIsStaticStaticPtr’
+ static-construction object ‘static_ptr1’:
+ data constructor name: StaticPtr
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘primes’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: StaticPtrInfo
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "main"
+ utilized items:
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "Example"
+ utilized items:
+ ordinary object ‘static_ptr1_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: (,)
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr1_sat_@name_suffix@’
+ item named ‘static_ptr1_sat_@name_suffix@’
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 27
+ utilized items: <none>
+ static-construction object ‘static_ptr1_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 20
+ utilized items: <none>
+ ordinary object ‘primes2_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘primes2_sat_@name_suffix@’
+ item named ‘isPrime_@name_suffix@’
+ item named ‘filter’
+ ordinary object ‘isPrime_@name_suffix@’:
+ arity: 1
+ literals: <none>
+ utilized items:
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals: <none>
+ utilized items:
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals: <none>
+ utilized items:
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ word 2
+ info table of ‘IS’
+ utilized items:
+ ordinary object ‘v_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$fIntegralInteger’
+ item named ‘$fNumNatural’
+ item named ‘^’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: <none>
+ ordinary object ‘v_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$fOrdNatural’
+ item named ‘<=’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: <none>
+ item named ‘.’
+ item named ‘primes’
+ item named ‘takeWhile’
+ ordinary object ‘isPrime_sat_@name_suffix@’:
+ arity: 2
+ literals: <none>
+ utilized items:
+ item named ‘$fIntegralNatural’
+ item named ‘divides’
+ item named ‘$fFoldableList’
+ item named ‘any’
+ item named ‘not’
+ static-construction object ‘primes’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘primes1_@name_suffix@’
+ item named ‘primes2_@name_suffix@’
+ ordinary object ‘primes2_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘primes2_sat_@name_suffix@’:
+ arity: 0
+ literals:
+ word 3
+ info table of ‘IS’
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ item named ‘$fEnumNatural’
+ item named ‘enumFrom’
+ ordinary object ‘primes1_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘primes1_sat_@name_suffix@’
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ static-construction object ‘primes1_sat_@name_suffix@’:
+ data constructor name: IS
+ lifted: yes
+ literals: word 2
+ utilized items: <none>
+ ordinary object ‘fibonaccisPtr’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr’
+ item named ‘$dTypeable2_@name_suffix@’
+ item named ‘$fIsStaticStaticPtr’
+ static-construction object ‘static_ptr’:
+ data constructor name: StaticPtr
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘fibonaccis’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: StaticPtrInfo
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "main"
+ utilized items:
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: top-level string "Example"
+ utilized items:
+ ordinary object ‘static_ptr_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘unpackCString#’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: (,)
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘static_ptr_sat_@name_suffix@’
+ item named ‘static_ptr_sat_@name_suffix@’
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 15
+ utilized items: <none>
+ static-construction object ‘static_ptr_sat_@name_suffix@’:
+ data constructor name: I#
+ lifted: yes
+ literals: word 24
+ utilized items: <none>
+ ordinary object ‘positiveFibonaccis2_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘positiveFibonaccis1_@name_suffix@’
+ item named ‘fibonaccis’
+ item named ‘positiveFibonaccis2_sat_@name_suffix@’
+ item named ‘zipWith’
+ static-construction object ‘positiveFibonaccis1_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘positiveFibonaccis_@name_suffix@’
+ item named ‘positiveFibonaccis2_@name_suffix@’
+ static-construction object ‘fibonaccis’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘fibonaccis1_@name_suffix@’
+ item named ‘positiveFibonaccis1_@name_suffix@’
+ ordinary object ‘positiveFibonaccis2_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$fNumNatural’
+ item named ‘+’
+ ordinary object ‘positiveFibonaccis_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘positiveFibonaccis_sat_@name_suffix@’
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ static-construction object ‘positiveFibonaccis_sat_@name_suffix@’:
+ data constructor name: IS
+ lifted: yes
+ literals: word 1
+ utilized items: <none>
+ ordinary object ‘fibonaccis1_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘fibonaccis1_sat_@name_suffix@’
+ item named ‘$fNumNatural’
+ item named ‘fromInteger’
+ static-construction object ‘fibonaccis1_sat_@name_suffix@’:
+ data constructor name: IS
+ lifted: yes
+ literals: word 0
+ utilized items: <none>
+ ordinary object ‘$dTypeable2_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ item named ‘$dTypeable_@name_suffix@’
+ item named ‘$dTypeable1_@name_suffix@’
+ item named ‘mkTrAppChecked’
+ ordinary object ‘$dTypeable1_@name_suffix@’:
+ arity: 0
+ literals: info table of ‘[]’
+ utilized items:
+ item named ‘$tcList’
+ item named ‘mkTrCon’
+ ordinary object ‘$dTypeable_@name_suffix@’:
+ arity: 0
+ literals: info table of ‘[]’
+ utilized items:
+ item named ‘$tcNatural’
+ item named ‘mkTrCon’
+ static-construction object ‘$tc'Nested’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 1
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Nested2_@name_suffix@’
+ item named ‘$krep17_@name_suffix@’
+ static-construction object ‘$tc'Nested2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Nested1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep17_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep16_@name_suffix@’
+ item named ‘$krep13_@name_suffix@’
+ static-construction object ‘$krep16_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcPerfectTree’
+ item named ‘$krep15_@name_suffix@’
+ static-construction object ‘$krep15_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep4_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tc'PerfectTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 1
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'PerfectTree2_@name_suffix@’
+ item named ‘$krep14_@name_suffix@’
+ static-construction object ‘$tc'PerfectTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'PerfectTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep14_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep13_@name_suffix@’
+ static-construction object ‘$krep13_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcPerfectTree’
+ item named ‘$krep12_@name_suffix@’
+ static-construction object ‘$krep12_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tcPerfectTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 0
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tcPerfectTree2_@name_suffix@’
+ item named ‘krep$*Arr*’
+ static-construction object ‘$tcPerfectTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tcPerfectTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$tc'Node’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 2
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Node2_@name_suffix@’
+ item named ‘$krep11_@name_suffix@’
+ static-construction object ‘$tc'Node2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Node1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep11_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep7_@name_suffix@’
+ item named ‘$krep10_@name_suffix@’
+ static-construction object ‘$krep10_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep_@name_suffix@’
+ item named ‘$krep9_@name_suffix@’
+ static-construction object ‘$krep9_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep7_@name_suffix@’
+ item named ‘$krep7_@name_suffix@’
+ static-construction object ‘$tc'Leaf’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 2
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tc'Leaf2_@name_suffix@’
+ item named ‘$krep8_@name_suffix@’
+ static-construction object ‘$tc'Leaf2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tc'Leaf1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep8_@name_suffix@’:
+ data constructor name: KindRepFun
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep7_@name_suffix@’
+ static-construction object ‘$krep7_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcBinTree’
+ item named ‘$krep6_@name_suffix@’
+ static-construction object ‘$krep6_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep5_@name_suffix@’
+ static-construction object ‘$krep5_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$tcBinTree’:
+ data constructor name: TyCon
+ lifted: yes
+ literals:
+ word @large_word@
+ word @large_word@
+ word 0
+ utilized items:
+ item named ‘$trModule’
+ item named ‘$tcBinTree2_@name_suffix@’
+ item named ‘krep$*->*->*’
+ static-construction object ‘$tcBinTree2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$tcBinTree1_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$krep4_@name_suffix@’:
+ data constructor name: KindRepTyConApp
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$tcTuple2’
+ item named ‘$krep3_@name_suffix@’
+ static-construction object ‘$krep3_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘$krep2_@name_suffix@’
+ static-construction object ‘$krep2_@name_suffix@’:
+ data constructor name: :
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$krep1_@name_suffix@’
+ item named ‘[]’
+ static-construction object ‘$krep1_@name_suffix@’:
+ data constructor name: KindRepVar
+ lifted: yes
+ literals: word 0
+ utilized items: <none>
+ static-construction object ‘$krep_@name_suffix@’:
+ data constructor name: KindRepVar
+ lifted: yes
+ literals: word 1
+ utilized items: <none>
+ static-construction object ‘$trModule’:
+ data constructor name: Module
+ lifted: yes
+ literals: <none>
+ utilized items:
+ item named ‘$trModule2_@name_suffix@’
+ item named ‘$trModule4_@name_suffix@’
+ static-construction object ‘$trModule4_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$trModule3_@name_suffix@’
+ utilized items: <none>
+ static-construction object ‘$trModule2_@name_suffix@’:
+ data constructor name: TrNameS
+ lifted: yes
+ literals: address ‘$trModule1_@name_suffix@’
+ utilized items: <none>
+ ordinary object ‘divides’:
+ arity: 3
+ literals: <none>
+ utilized items:
+ ordinary object ‘$dReal_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 1
+ literals:
+ word 0
+ info table of ‘IS’
+ utilized items:
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘fromInteger’
+ item named ‘$p1Real’
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 3
+ literals: <none>
+ utilized items: item named ‘mod’
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items:
+ ordinary object ‘divides_sat_@name_suffix@’:
+ arity: 0
+ literals: <none>
+ utilized items: item named ‘==’
+ item named ‘$p1Ord’
+ item named ‘$p2Real’
+ item named ‘$p1Integral’
+ ordinary object ‘Node’:
+ arity: 3
+ literals: info table of ‘Node’
+ utilized items: <none>
+ ordinary object ‘Leaf’:
+ arity: 1
+ literals: info table of ‘Leaf’
+ utilized items: <none>
+ ordinary object ‘Nested’:
+ arity: 1
+ literals: info table of ‘Nested’
+ utilized items: <none>
+ ordinary object ‘PerfectTree’:
+ arity: 1
+ literals: info table of ‘PerfectTree’
+ utilized items: <none>
+data constructor info tables:
+ info table of ‘PerfectTree’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Nested’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Leaf’:
+ number of words for pointers: 1
+ number of words for non-pointers: 0
+ info table of ‘Node’:
+ number of words for pointers: 3
+ number of words for non-pointers: 0
+top-level strings:
+ $tc'Nested1_@name_suffix@: "'Nested"
+ $tc'PerfectTree1_@name_suffix@: "'PerfectTree"
+ $tcPerfectTree1_@name_suffix@: "PerfectTree"
+ $tc'Node1_@name_suffix@: "'Node"
+ $tc'Leaf1_@name_suffix@: "'Leaf"
+ $tcBinTree1_@name_suffix@: "BinTree"
+ $trModule3_@name_suffix@: "Example"
+ $trModule1_@name_suffix@: "main"
+breakpoints: <none>
+static-pointer table entries:
+ @hash@: static_ptr
+ @hash@: static_ptr1
+HPC information: <none>
+
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/97ab9bcd932d759d771c562f3ebae8d…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/97ab9bcd932d759d771c562f3ebae8d…
You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
1
0
[Git][ghc/ghc][wip/fendor/external-unit-db-cache] Fixup: sort imports
by Hannes Siebenhandl (@fendor) 21 Jul '26
by Hannes Siebenhandl (@fendor) 21 Jul '26
21 Jul '26
Hannes Siebenhandl pushed to branch wip/fendor/external-unit-db-cache at Glasgow Haskell Compiler / GHC
Commits:
b4b08a95 by fendor at 2026-07-21T16:10:05+02:00
Fixup: sort imports
- - - - -
1 changed file:
- compiler/GHC/Unit/External/ModuleOrigin.hs
Changes:
=====================================
compiler/GHC/Unit/External/ModuleOrigin.hs
=====================================
@@ -7,12 +7,12 @@ module GHC.Unit.External.ModuleOrigin (
originEmpty,
) where
+import Data.Semigroup qualified as Semigroup
import GHC.Prelude
import GHC.Unit.External.Validate
import GHC.Unit.Info
import GHC.Utils.Outputable
import GHC.Utils.Panic
-import qualified Data.Semigroup as Semigroup
-- | Given a module name, there may be multiple ways it came into scope,
-- possibly simultaneously. This data type tracks all the possible ways
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b4b08a95820c62394830a3b93b1d89d…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b4b08a95820c62394830a3b93b1d89d…
You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
1
0
[Git][ghc/ghc][wip/jeltsch/textual-bytecode-output] 221 commits: Fixes for black holes
by Wolfgang Jeltsch (@jeltsch) 21 Jul '26
by Wolfgang Jeltsch (@jeltsch) 21 Jul '26
21 Jul '26
Wolfgang Jeltsch pushed to branch wip/jeltsch/textual-bytecode-output at Glasgow Haskell Compiler / GHC
Commits:
63ce5770 by Luite Stegeman at 2026-05-28T12:23:35-04:00
Fixes for black holes
- suspend duplicate work for eager black holes
- detect eager black holes in checkBlockingQueues
- don't overwrite existing black holes even if they're not
in an eager blackhole frame
- don't deadlock on self when thunk is already blackholed
Fixes #26936
- - - - -
037a80dc by Tom McLaughlin at 2026-05-28T12:24:36-04:00
Event/Windows.hsc: rethrow exceptions in overlapped IO
This prevents the WinIO manager from swallowing exceptions in overlapped IO. It
was added to make WinIO support possible in the `network` library. See
https://gitlab.haskell.org/ghc/ghc/-/issues/27283.
We also bump __IO_MANAGER_WINIO__ to 2 so libraries can gate on this using CPP.
- - - - -
2d53bcdb by Wolfgang Jeltsch at 2026-05-28T12:25:21-04:00
Allow `downsweep` to use nodes of an existing module graph
To this end, `downsweep` has not been able to use the nodes of a module
graph obtained from a previous downsweeping round. In some GHC API
applications, downsweeping is performed somewhat incrementally and
therefore could profit from reusing such existing results. This
contribution makes this possible.
Resolves #27054.
Co-authored-by: Matthew Pickering <matthewtpickering(a)gmail.com>
- - - - -
f4fbb583 by Simon Jakobi at 2026-05-28T12:26:04-04:00
Add regression test for T11226
Closes #11226.
- - - - -
ed29a5e6 by Sven Tennie at 2026-05-28T17:30:36-04:00
Add optional config setting for LibDir (#19174)
Previously, the `libDir` was derived from `topDir`. This won't work for
inplace stage2 cross-compilers where binaries and libraries are in
different stage dirs (`_build/stage1/` for executables and
`_build/stage2` for libraries).
`LibDir` is set in the inplace `settings` files. For bindists, we
generate a new `settings` file with no `LibDir` entry. GHC then defaults
to use `topDir` as `libDir` again. This keeps the bindist relocatable.
If `LibDir` is a relative path, it is interpreted relatively to
`topDir`.
The global package db is part of the `lib/` folder. If we want to point
for inplace cross-compilers to the succeeding stage's folder, this is
done by setting `LibDir`. Thus, the global package db must be found
relative to `libDir`` (which may default to `topDir` or be set by
`LibDir`).
The complexity of settings becomes scary. So, add a test to ensure
`LibDir` works as expected.
- - - - -
8339cf8f by Sven Tennie at 2026-05-28T17:30:36-04:00
Add Haddock to FileSettings
Helping to understand the fields' meanings without deeper analyses.
- - - - -
4ce251e4 by Sylvain Henry at 2026-05-28T17:31:39-04:00
foundation test: skip signed minBound `quot` (-1) (#27222)
`minBound `quot` (-1)` for fixed-width signed integers is platform
dependent: the mathematical result -minBound is not representable in
the type. On x86, IDIV traps; LLVM's sdiv is undefined behaviour in
this case; on AArch64/RISC-V, SDIV wraps to minBound.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply(a)anthropic.com>
- - - - -
b8ba7e61 by Simon Jakobi at 2026-05-28T17:32:23-04:00
Prevent dictionary-passing in checkTyEqRhs
...by pre-specializing it to TcM.
Previously, wherever checkTyEqRhs was used in other modules, the
Core showed dictionary passing ($fMonadIOEnv). The added SPECIALIZE
pragma prevents this.
- - - - -
d603477f by David Eichmann at 2026-05-29T13:17:12-04:00
Hadrian: create a ghc-internal .def file per ghc-internal dll
The .def file generated from rts/win32/libHSghc-internal.def.in contains
the name of the ghc-internal dll. The correct dll name differs based
on if the dll is inplace/final and if using the Dynamic way. Previously,
this was not accounted for and inconsistent dlls names where used. That
led to failure when loading dlls at runtime in experiments with windows
dynamic linking.
- - - - -
1fc21753 by Sylvain Henry at 2026-05-29T13:18:14-04:00
ghc-bignum: copy backend interface haddocks to Native backend (#27305)
The haddock comments documenting the BigNat backend interface (function
contracts, expected MutableWordArray# sizes, return-value semantics, etc.)
were attached to the FFI backend module. Copy them to the Native backend
so they remain in tree once the FFI backend is removed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply(a)anthropic.com>
- - - - -
717059df by Sylvain Henry at 2026-05-29T13:18:14-04:00
ghc-bignum: remove FFI backend (#27305)
The FFI backend of ghc-bignum (now part of ghc-internal) had no known
users and is easy to recreate by relinking ghc-internal with a custom
backend. Remove the backend module, the bignum-ffi cabal flag, and the
ffi option from Hadrian's --bignum selector. The backend interface
documentation now lives in the Native backend module.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply(a)anthropic.com>
- - - - -
4bb3b1d8 by Sylvain Henry at 2026-05-29T13:18:14-04:00
ghc-bignum: remove Check backend (#27305)
The Check backend of ghc-bignum (now part of ghc-internal) compared the
selected backend's output against the Native backend for validation.
It had no known users. Remove the backend module, the bignum-check
cabal flag, the bignumCheck Hadrian flavour field, and the check-
prefix in Hadrian's --bignum selector.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply(a)anthropic.com>
- - - - -
6b3044a0 by David Eichmann at 2026-05-30T11:58:48-04:00
Add code comments to allocator code
- - - - -
f4e04210 by Matthew Pickering at 2026-05-30T11:59:34-04:00
hadrian: Refactor system-cxx-std-lib rules
I noticed a few things wrong with the hadrian rules for
`system-cxx-std-lib` rules.
* For `text` there is an ad-hoc check to depend on `system-cxx-std-lib`
outside of `configurePackage`.
* The `system-cxx-std-lib` dependency is not read from cabal files.
* Recache is not called on the packge database after the `.conf` file is
generated, a more natural place for this rule is `registerRules`.
Treating this uniformly like other packages is complicated by it not
having any source code or a cabal file. However we can do a bit better
by reporting the dependency firstly in `PackageData` and then needing
the `.conf` file in the same place as every other package in
`configurePackage`.
This commit increases the `shakeVersion`, to provide backwards
compatibility to previous builds with different PackageData.
Fixes #25303
Co-authored-by: Sven Tennie <sven.tennie(a)gmail.com>
- - - - -
576987d0 by Simon Jakobi at 2026-06-02T04:53:36-04:00
compiler: use nubOrd from containers
Address #27103 by replacing GHC.Utils.Misc.ordNub[On] with
Data.Containers.ListUtils.nubOrd[On].
Note that nubOrd suffers from a small inefficiency, a fix for which
will be included in the next containers release:
https://github.com/haskell/containers/issues/1202
- - - - -
deea53c3 by David Eichmann at 2026-06-02T04:54:22-04:00
Hadrian: disable response files for GHC/Haddock builders on non-Windows
This makes debugging build errors easier on non-windows hosts.
See issue #27230
- - - - -
f2f5c6ba by Nikita Efremov at 2026-06-02T16:04:54+00:00
fix typo : compete with performance, not complete
- - - - -
5524ea0e by Wolfgang Jeltsch at 2026-06-03T08:01:26-04:00
Make the current `base` buildable with GHC 9.14
This comprises the following changes:
* Disable some imports into `GHC.Base` for GHC 9.14
* Disable some imports into `Prelude` for GHC 9.14
* Disable separate `ArrowLoop` import for GHC 9.14
* Disable `GHC.Internal.STM` import for GHC 9.14
* Disable `GHC.Internal.Unicode.Version` import for GHC 9.14
* Disable `GHC.Internal.TH.Monad` import for GHC 9.14
* Add alternative `fixIO` import for GHC 9.14
* Add alternative `unsafeCodeCoerce` import for GHC 9.14
* Disable hiding of imported SIMD operations for GHC 9.14
* Disable use of GHC 9.14’s `printToHandleFinalizerExceptionHandler`
* Enable use of `getFileHash` from `ghc-internal` for GHC 9.14
* Make `thenA` available for GHC 9.14
* Make `thenM` available for GHC 9.14
* Disable translation of `IoManagerFlagPoll` for GHC 9.14
* Add `hGetNewlineMode` for GHC 9.14
- - - - -
d3438055 by Enrico Maria De Angelis at 2026-06-03T08:02:17-04:00
Fix #27067 - Clarify haddocks on `minusNaturalMaybe`
- - - - -
f9bcfac2 by sheaf at 2026-06-03T14:47:19-04:00
Avoid mkTick in Core Prep breaking ANF
As discovered in #27182, mkTick can break ANF. This patch introduces a
variant of mkTick that skips the single optimisation that could break
ANF. This is preferrable over switching to the raw Tick constructor,
as the latter may introduce spurious cost centres in profiling reports.
This is a temporary measure until we more thoroughly refactor how
mkTick works (see #27141).
See Note [mkTick breaks ANF] in GHC.CoreToStg.Prep.
Fixes #27182
- - - - -
cf1fd661 by Artem Pelenitsyn at 2026-06-03T14:48:09-04:00
clarify comment for getSizeofMutableByteArray#: we get the size in bytes, not "elements"
- - - - -
a3b431f3 by David Eichmann at 2026-06-04T10:10:19+00:00
Hadrian: convert env variable ACLOCAL_PATH to unix paths.
Convert ACLOCAL_PATH to a unix style path when invoking autoreconf.
Autoreconf doesn't handle windows paths.
See Note [Autoreconf unix paths from ACLOCAL_PATH].
Fixes #27311
- - - - -
18f6138a by Simon Jakobi at 2026-06-04T20:20:31-04:00
testsuite: Deduplicate --only test names
config.only is assumed to be a set, but supplying --only overwrote it
with the (list) argparse result, which can contain duplicates. When a
test ran, config.only.remove(name) dropped only the first occurrence,
so a duplicated name lingered and was later misreported as a
"test not found" framework failure. Store it as a set instead.
Fixes #27322
Co-Authored-By: Claude Opus 4.7 <noreply(a)anthropic.com>
- - - - -
2f3cc9ff by Simon Jakobi at 2026-06-08T07:55:49-04:00
testsuite: detect fast bignum via ghc-internal, not removed ghc-bignum
The ghc-bignum package was merged into ghc-internal, so the BIGNUM_GMP
probe in test.mk ran `ghc-pkg field ghc-bignum exposed-modules`, which
fails with "cannot find package ghc-bignum". That error went to stderr
and leaked into the captured stderr of every makefile_test, causing
spurious [bad stderr] failures across the suite. The probe also silently
returned empty, so config.have_fast_bignum was wrongly False even on GMP
builds.
Probe ghc-internal's extra-libraries for the gmp library instead: the
GMP backend module is an other-module (not exposed), but GMP_LIBS adds
gmp to extra-libraries only on a GMP build, so this distinguishes the
backends. Redirect stderr to keep any future missing-package error off
the harness's stderr.
This also removes a stale comment as per suggestion from hsyl20.
Co-Authored-By: Claude Opus 4.7 <noreply(a)anthropic.com>
- - - - -
eb3bf6e7 by Alan Zimmerman at 2026-06-08T07:56:32-04:00
EPA: Rename Transform.anchorEof to addModuleCommentOrigDeltas
This now matches what it actually does.
- - - - -
498bb21a by David Eichmann at 2026-06-09T18:02:39-04:00
Hadrian: avoid response files when command line is short enough
This replaces the logic of always using response files on Windows.
With the new condition based on command line lenght, reponse files
can be avoided in many more cases (on windows).
Now that response files are only used in a small number of cases,
response files are always kept and the -r / --keep-response-files
command line options have been removed
The response file paths are nolonger randomized. They are placed in the
`_build/rsp` directory. This ensures they are ignored by git and we
that Hadrian reuses response file paths when rebuilding rather than
leaving stale response files around.
Update user guide putting response files in its own section
- - - - -
87f510a5 by Simon Hengel at 2026-06-09T18:03:25-04:00
Don't use non-breaking spaces
- - - - -
41a19379 by David Eichmann at 2026-06-09T18:04:11-04:00
Hadrian: remove unused wrapper scripts from windows bindist
These wrapper scripts are only installed on non-relocatable builds
which are not generally supported on windows.
- - - - -
ce01ccb6 by sheaf at 2026-06-10T05:08:48-04:00
Don't drop ticks around variables of type `IO ()`
GHC.Core.Utils.mkTick is responsible for placing a tick on a Core
expression. It contains logic for dropping SCCs (non-counting profiling
ticks) around non-function variables, as such variables cannot
meaningfully contribute to profiles. However, the logic for what counts
as a function was incorrect: it used `isFunTy` which returns 'False' for
types such as 'IO ()' where the function arrow is hidden under a
newtype.
We now use 'mightBeFunTy' instead of 'isFunTy'. This ensures we don't
drop ticks in cases we aren't sure.
On the way, we improve the documentation of 'isFunTy', 'isPiTy' and
'mightBeFunTy', and update the latter's implementation to consistently
handle unary classes.
Fixes #27225
-------------------------
Metric Decrease:
T5642
-------------------------
- - - - -
d311c4f1 by Simon Jakobi at 2026-06-10T05:09:32-04:00
testsuite: Add regression test for #4081
Check that a strict constructor field is unboxed once outside an
enclosing loop, not re-inspected each iteration (the float-out
case-floating from 9cb20b488). Uses simonpj's `data T a = T !a` example
from the ticket; T4081.stderr captures the expected Core.
Co-Authored-By: Claude Opus 4.7 <noreply(a)anthropic.com>
- - - - -
333df444 by sheaf at 2026-06-10T05:10:25-04:00
Check for cabal-install >= 3.12 upfront
Starting with commit 8cb99552f607f6bc4000e45ab32532d50c8bb996, Hadrian
requires cabal-install >= 3.12 in order to use the 'cabal path' command
that was introduced in version 3.12, as per
https://github.com/haskell/cabal/blob/a51c4ee1556d816ad86e90db7e6330dd51b0b…
This was not reflected in the Hadrian build script, causing a delayed
build failure instead of enforcing the version requirement upfront,
which this patch does.
Fixes #27317
- - - - -
98c20394 by sheaf at 2026-06-10T05:11:09-04:00
Fix crash in Data.Data instance for HsCtxt
The Data.Data instance for HsCtxt contained an error for the 'toConstr'
method, which could trigger for example when looking at -ddump-tc-ast
traces. Replace it with the 'abstractConstr' pattern used in the rest of
the codebase.
- - - - -
5ac9ce7d by Zubin Duggal at 2026-06-10T21:26:32+05:30
hadrian: Remove old package.conf files when generating new ones
Old package.conf files might exists with different hashes, causing issues like #26661
Fixes #26661
- - - - -
c9015f09 by sheaf at 2026-06-11T12:40:28-04:00
Fix AArch64 clobbering bug for MUL2
On AArch64, the code generator could clobber one of the input operands
when computing the lower bits of a MUL2 operation. This rendered invalid
the subsequent computation of the high bits.
This commit fixes that by using a temporary register. The register
allocator can remove the redundant move in the common case when the
registers do not conflict.
Fixes #27046
- - - - -
7ab90288 by Rodrigo Mesquita at 2026-06-11T12:41:11-04:00
fix: make T27131 less flaky
It seems that T27131 fails flakily in a race where we check the flag
before the capability had the chance to process the mailbox which sets
the flag. This seemingly should only happen if the capability ends up
being the same for setting and checking the flag.
- - - - -
8965cb76 by Marc Scholten at 2026-06-12T04:53:22-04:00
haddock: render modules concurrently
- - - - -
8cc0b64a by Duncan Coutts at 2026-06-12T04:54:06-04:00
Promote HAVE_PREEMPTION from Timer.c to OSThreads.h
We will want to know about HAVE_PREEMPTION in more places.
HAVE_PREEMPTION tells us that we do have OS threads available,
irrespective of whether THREADED is defined. In particular,
HAVE_PREEMPTION is defined on all proper OSs, but not on WASM (and
hyopthetically may not be true on some other platforms like
micro-controllers, RTOSs, VM hypervisors etc).
- - - - -
cce574ed by Duncan Coutts at 2026-06-12T04:54:06-04:00
Define ACQUIRE_LOCK_ALWAYS and friends
Fix issue #27335
Like the atomic _ALWAYS variants, these lock actions are always defined,
rather than being dependent on whether we are in the THREADED case. All
the "normal" LOCK macros are defined to be no-ops when !THREADED.
The use case for the _ALWAYS variants is where we are using OS threads
even in the non-threaded RTS. This includes everything to do with the
timer/ticker thread, which is used in the non-threaded RTS too.
In particular, we will want to use this for eventlog things, because the
timer thread performs eventlogging concurrently with the main
capability, even in the non-threaded RTS.
- - - - -
1f28d1f6 by Duncan Coutts at 2026-06-12T04:54:06-04:00
Use ACQUIRE/RELEASE_LOCK_ALWAYS with eventBufMutex
Even in the non-threaded RTS the eventBufMutex is needed by both the
main capability and the timer/ticker thread, so always use the mutex.
This should fix #25165 which is about the main capability and the timer
thread posting events to the eventlog buffer concurrently and thereby
corrupting the buffer data.
- - - - -
0ff29782 by Duncan Coutts at 2026-06-12T04:54:06-04:00
Expose eventBufMutex in the EventLog interface/header
We will need it in forkProcess to ensure we don't write to the global
eventlog buffer concurrently with trying to flush eventlog buffers and
do the fork().
- - - - -
7a688395 by Duncan Coutts at 2026-06-12T04:54:07-04:00
Split flushAllCapsEventsBufs into safe and unlocked version
Following the convention that unlocked versions have a trailing _
underscore in their name. This one requires the caller to hold the
eventlog global buffer mutex. We will need this in forkProcess.
- - - - -
341ed474 by Duncan Coutts at 2026-06-12T04:54:07-04:00
Remove redundant use of stopTimer in setNumCapabilities
Historically, the comment here was:
We must stop the interval timer while we are changing the
capabilities array lest handle_tick may try to context switch
an old capability. See #17289.
and
We must disable the timer while we do this since the tick handler may
call contextSwitchAllCapabilities, which may see the capabilities array
as we free it.
What this refers to is that historically, when changing the number of
capabilities, the array of capabilities was reallocated to a new size,
allocating new ones and freeing the old ones, thus invalidating all
existing capbility pointers.
Strangely, for good measure the code used to call stopTimer twice (hence
the two similar comments above).
However, since commit a3eccf06292dd666b24606251a52da2b466a9612, the
capabilities array is no longer reallocated. Instead the array is
allcoated once on RTS startup to the maximum size it could ever be
allowed to be, and then capabilities get enabled/disabled at runtime. So
the capability pointers never become invalid anymore. At worst, they may
point to capabilities that are disabled.
Thus we no longer need to stop the timer (twice) while we change the
number of enabled capabilities. This also partially solves issue #27105,
which notes that stopTimer is being used as if it were synchronous, when
it is not. At least for this case, the solution is that stopTimer is not
needed at all!
- - - - -
674858e3 by Duncan Coutts at 2026-06-12T04:54:07-04:00
Remove redundant use of stopTimer in forkProcess
but replace it with taking the eventlog buffer lock during the fork.
Fixes issue #27105
The original reason to block the timer during a fork was that
historically the timer was implemented using a periodic timer signal,
and the signal itself would interrupt the fork system call (returning
EINTR). For large processes (where fork() takes a while) this could
permanently livelock: the timer always would go off before the fork
could complete, which got retried in a loop forever.
The timer is no longer implemented as a unix signal, but uses threads.
Thus the original problem no longer exists. The only remaining reason to
block the timer tick is to prevent actions taken by the tick from
interfering with the delicate process involved in fork (taking a load of
locks and pausing everything).
The only thing we need to do is to prevent the eventlog from being
written to or flushed while the fork is taking place. To achieve this
all we need to do is hold the mutex for the global eventlog buffer.
This removes the last use of stopTimer that expects stopTimer to work
synchronously (which it was not) and thus solves issue #27105. To be
clear, we solve issue #27105 not by making stopTimer synchronous, but by
eliminating the use sites that expected it to be synchronous.
- - - - -
40764930 by sheaf at 2026-06-12T14:54:43-04:00
Add type family performance test for #26426
Some GHC versions produced large numbers of coercions after typechecking
and desugaring when compiling the program in #26426:
Version | Typechecker time | Typechecker allocations | Coercions
-------:|-----------------:|------------------------:|---------:
9.6 | 47 ms | 48 MB | 110k
9.8 | 1000 ms | 486 MB | 10,437k
9.10 | 922 ms | 489 MB | 10,436k
9.12 | 906 ms | 482 MB | 10,437k
9.14 | 63 ms | 55 MB | 333k
10.0 | 47 ms | 64 MB | 35k
The improvement 9.12 -> 9.14 was due to commit 22d11fa818fae2c95c494fc0fac1f8cb4c6e7cb6,
while the improvement 9.14 -> 10.0 was due to commit 0b7df6db9e46df40e86fbff1a66dc10440b99db5.
As the behaviour of GHC seems better than it's ever been on this program,
we declare victory, adding this performance test to ensure we don't
regress on this program.
On the way, we update Note [Combining equalities] in GHC.Tc.SolveR.Equality
with the explanation of the 9.12 -> 9.14 improvement (getting rid of an
exponential blowup in coercion sizes), and we update
Note [Exploiting closed type families] in GHC.Tc.Solver.FunDeps with
the explanation of the 9.14 -> 10.0 improvement (bringing down coercion
size growth from cubic to quadratic).
- - - - -
0f3d0a71 by Zubin Duggal at 2026-06-12T14:55:30-04:00
compiler: mark tool messages as errors/warnings depending on the exit code
Fixes #27370
- - - - -
d9ea2d76 by mangoiv at 2026-06-13T04:41:51-04:00
libraries/process: bump submodule to v1.6.30.0
- bump the submodule to the appropriate tag
- suppress benign warning resulting from the change
- - - - -
6ebaaba3 by David Eichmann at 2026-06-13T04:42:37-04:00
ghc-toolchain: don't throw when candidate executables are not found
Fixes #27369
- - - - -
6c65e1e1 by David Eichmann at 2026-06-13T04:43:23-04:00
CI: lint-changelog checks for no-changelog label in script instead of rules
- - - - -
bab37cc6 by konsumlamm at 2026-06-13T19:10:21+02:00
Implement CLC proposal #378
Add `Data.Double` and `Data.Float` modules
Document that GHC uses IEEE 754
- - - - -
fb5246ad by fendor at 2026-06-15T18:07:23-04:00
Drop `preloadClosure` from `UnitState`
It is always hard-coded to the same value.
Backpack Unit instantiation isn't using it any more.
Allows us to simplify the API and get rid of `improveUnit`.
- - - - -
291ce3aa by ARATA Mizuki at 2026-06-15T18:08:26-04:00
RISC-V NCG: Zero-extend the result of castFloatToWord32
According to the ISA manual, FMV.X.W sign-extends the result.
We need to truncate the result to avoid creating an exotic Word32 value.
Fixes #27300
- - - - -
011be91f by ARATA Mizuki at 2026-06-15T18:08:26-04:00
RISC-V NCG: Treat d28-d31 (ft8-ft11) as caller-saved
According to the calling convention, the registers d28-d31 (ft8-ft11) are caller-saved.
Fixes #27306
- - - - -
e8a54713 by ARATA Mizuki at 2026-06-15T18:08:26-04:00
RISC-V NCG: Set rounding mode when emitting `truncate`
If we omit the rounding mode for `fcvt`, `dyn` will be used.
We do not want that for `truncate`, so we set `rtz`.
In other places, we set `rne` because we do not use the dynamic rounding mode.
Fixes #27303
- - - - -
9438bec7 by Zubin Duggal at 2026-06-15T18:09:11-04:00
rts: fix validate build with gcc 16. `__attribute__((regparm(1)))` is ignored on x86_64 and now
gcc warns that it is ignored:
rts/sm/Evac.h:35:1: error:
error: ‘regparm’ attribute ignored [-Werror=attributes]
See https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=ccead81bbc39668376eb5cf47066a…
Fixes #27366
- - - - -
893e6133 by Andrew Lelechenko at 2026-06-15T23:55:36+01:00
base: more NonEmpty zips
CLC proposal: https://github.com/haskell/core-libraries-committee/issues/409
- - - - -
1314f2fd by David Eichmann at 2026-06-16T05:46:52-04:00
Hadrian: fix ghc-internal .def file name
- - - - -
7f72bcb3 by mangoiv at 2026-06-16T05:47:39-04:00
compiler: ignore camelCase and Eta reduce hlint hints
These do not cohere with the style used in GHC. After disabling them,
hlint lints are much less noisy again.
- - - - -
842bef9f by Alan Zimmerman at 2026-06-16T05:48:25-04:00
EPA: Use standard type family declaration for Anno
- - - - -
f6d30767 by Wolfgang Jeltsch at 2026-06-16T15:32:34-04:00
Fix two issues in the documentation of pipeline interruption
One issue is a typo (“interreuptible”), the other one the lack of an end
of a sentence, which has been reconstructed from the message of
633bbc1fd4762a2bb73ba1c5b9e0c279f1dd3c40, the commit that introduced
said documentation.
- - - - -
a3fa10e0 by Christian Georgii at 2026-06-16T15:33:26-04:00
Find plugins in sibling home units in multiple-home-unit sessions
In a multiple-home-unit session (e.g. `cabal repl --enable-multi-repl` or HLS), enabling a plugin with -fplugin that is defined in (or reexported by) another home unit failed with a "hidden package" error. The plugin module finder only searched the current home unit and the registered external packages, never the sibling home units.
findPluginModuleNoHsc now searches the home units that the current home unit depends on, following module reexports and respecting hidden modules, exactly as ordinary import resolution does in findImportedModuleNoHsc. To avoid two divergent copies of this logic, the shared home-unit search (the current home unit first, then its dependencies in priority order, with the accompanying ordering invariant) is extracted into findHomeModuleAmongDeps, which both findImportedModuleNoHsc and findPluginModuleNoHsc now call.
Add testsuite/tests/driver/multipleHomeUnits/plugin01, which loads a plugin as byte-code from a sibling home unit, and plugin02, in which the consumer enables a plugin reexported by a sibling home unit without depending on the plugin's own home unit directly.
Fixes #27349
- - - - -
d216412b by Ian-Woo Kim at 2026-06-16T20:25:57-04:00
Make the order of usages deterministic
It has been observed that the ordering of usages can be non-determinstic
in parallel builds. Therefore, this contribution introduces sorting of
usages based on a platform- and race-independent sorting criterion.
Resolves #26877.
Co-authored-by: Wolfgang Jeltsch <wolfgang(a)well-typed.com>
- - - - -
8e1cc105 by Wolfgang Jeltsch at 2026-06-16T20:25:57-04:00
Change the descriptions of two existing changelog entries
The descriptions now describe the changes in a user-friendly manner, as
opposed to describing the contributions that led to these changes in a
developer-friendly manner.
- - - - -
636c1c7a by Ian Duncan at 2026-06-16T20:26:50-04:00
AArch64: use SXTH, not SXTW, for W32 signExtendReg
signExtendReg was using SXTH (sign-extend halfword, 16-bit) for
W32-to-W64 sign extension. This should be SXTW (sign-extend word,
32-bit). SXTH only sign-extends the lower 16 bits, producing wrong
results for 32-bit values whose bit 15 differs from bit 31.
Other fixes:
- At sub-W64, code gen for MO_S_Mul2 should use W32 registers for
SMULL source operands as per the ARM spec (SMULL Xd, Wn, Wm),
and not W64.
- Ensure signExtendReg uses the source width for the source operand
in SXTW/SXTH/SXTB instructions. GNU as requires sxtw Xd,Wn (not
sxtw Xd,Xn), while LLVM's integrated assembler on macOS is lenient.
- Fix overflow flag computation for `MO_S_Mul2`. The overflow bit
was exactly inverted for sub-W64 operands.
Fixes #26978 and #27047
- - - - -
b734c75d by Igor Ranieri at 2026-06-16T20:27:32-04:00
haddock: Update CONTRIBUTING with missing step, add missing test
dependency
- - - - -
7fe4f2ec by Luite Stegeman at 2026-06-17T05:35:09-04:00
tag inference: don't confuse functions with their return values
inferTagRhs was mixing up taggedness for closures and return values
for function closures. We really shouldn't assign TagTuple to a
properly tagged function returning a tuple.
We fix this by keeping track of functions (TagFun) separately from
values (TagVal) and keeping track of their return value. TagFun is
also used for join points.
fixes #27005
- - - - -
4671c126 by Sebastian Graf at 2026-06-17T05:35:55-04:00
Seed the simplifier's in-scope set for open expressions
simplifyExpr simplifies expressions typed at the GHCi prompt and the
results of Template Haskell splices. Such an expression may be open: at a
GHCi debugger breakpoint its free variables include RuntimeUnk skolems
standing for as-yet-unknown types.
The simplifier began with an in-scope set holding only the wildcard
binder, so when it instantiated the unsafeCoerce# wrapper that GHCi
builds around a result, it formed a substitution whose range mentioned a
free skolem that was not in scope. That breaks the substitution invariant
and, in a compiler built with assertions, trips substTy's sanity check.
Seed the initial in-scope set with the free variables of the expression.
For a closed expression this adds nothing.
See Note [Seed the in-scope set for open expressions].
Fixes #17833 and its duplicate #21118.
- - - - -
67d41299 by Sebastian Graf at 2026-06-18T05:18:24-04:00
Desugar a `case` scrutinee only once (#27383, #20251)
In `dsExpr` for `HsCase` we desugared the scrutinee /twice/: once to
build the Core `case` itself, and again inside `matchWrapper`, which
re-desugared the source scrutinee (via `addHsScrutTmCs`) purely to
record long-distance information for the pattern-match checker.
For a single `case` that is merely wasteful. But for nested cases it
is catastrophic. Consider
case (case (case e of ... ) of ... ) of ...
Desugaring the outer scrutinee desugars the middle `case` twice, each
of which desugars the inner `case` twice, and so on. The work doubles
at every level, so desugaring takes O(2^n) time in the nesting depth.
That is the blowup reported in #27383; it is also what makes the
machine-generated program in #20251 take an age to compile.
The fix is simple. `matchWrapper` is handed the scrutinee anyway, so
we give it the Core expression we have /already/ desugared, and record
the long-distance term constraint with `addCoreScrutTmCs` instead of
re-desugaring from source. This is just what `matchSinglePatVar`
already does for single-pattern matches.
So:
* `matchWrapper` now takes `Maybe [CoreExpr]` rather than
`Maybe [LHsExpr GhcTc]`.
* The `HsCase` equation of `dsExpr` passes the already-desugared
`core_discrim`; the arrow desugarer passes its match variables.
* `addHsScrutTmCs` had no other use, so it is gone.
Desugaring is now linear in the nesting depth. (The coverage checker
still runs `simpleOptExpr` over each scrutinee, which leaves the total
at O(n^2); that is ample.) The long-distance information itself is
unchanged: the checker sees precisely the Core that backs the
generated code.
Test: deSugar/should_compile/T27383
- - - - -
fa5defde by Rodrigo Mesquita at 2026-06-18T05:19:11-04:00
fix: Save FastStrings in the PMC
There is no point in adding the unique to the occurrence FastString we
create, since it is part of the Id anyway.
Adding it to the FastString, meant each FastString was unique
unnecessarily!
In a separate branch, running the compiler on test `InstanceMatching`
observed 30000 `FastString`s created by this code path.
Plus, `fsLit "pm"` follows the existing pattern in `mkPmId`.
- - - - -
4efb4a66 by Alan Zimmerman at 2026-06-18T14:41:14-04:00
TTG: Add extension points to HsConDetails
Extend HsConDetails as
data HsConDetails p arg rec
= PrefixCon !(XPrefixCon p) [arg] -- C @t1 @t2 p1 p2 p3
| RecCon !(XRecCon p) rec -- C { x = p1, y = p2 }
| InfixCon !(XInfixCon p) arg arg -- p1 `C` p2
| XHsConDetails !(XXHsConDetails p)
type family XPrefixCon p
type family XRecCon p
type family XInfixCon p
type family XXHsConDetails p
- - - - -
c8d27dd4 by Simon Jakobi at 2026-06-18T14:41:59-04:00
CI: quiet submodule clean output in after_script and setup
The clean and cleanup_submodules functions ran 'git submodule foreach
git clean -xdf', flooding the job log with 'Entering ...' and
'Removing ...' lines. Pass --quiet to 'git submodule' and -q to 'git
clean' to drop the success output; errors are still reported.
Co-Authored-By: Claude Opus 4.8 <noreply(a)anthropic.com>
- - - - -
09326ca6 by Matthew Pickering at 2026-06-20T23:41:12+02:00
Add missing req_interp modifier to T18441fail3 and T18441fail19
These tests require the interpreter but they were failing in a different
way with the javascript backend because the interpreter was disabled and
stderr is ignored by the test.
- - - - -
521e55bf by Matthew Pickering at 2026-06-20T23:41:13+02:00
hadrian: Fill in more of the default.host toolchain file
When you are building a cross compiler this file will be used to build
stage1 and it's libraries, so we need enough information here to work
accurately. There is still more work to be done (see for example, word
size is still fixed).
- - - - -
23c9b6c3 by Matthew Pickering at 2026-06-20T23:42:52+02:00
hadrian: Build stage 2 cross compilers
* Most of hadrian is abstracted over the stage in order to remove the
assumption that the target of all stages is the same platform. This
allows the RTS to be built for two different targets for example.
* Abstracts the bindist creation logic to allow building either normal
or cross bindists. Normal bindists use stage 1 libraries and a stage 2
compiler. Cross bindists use stage 2 libararies and a stage 2
compiler.
* hadrian: Make binary-dist-dir the default build target. This allows us
to have the logic in one place about which libraries/stages to build
with cross compilers. Fixes #24192
New hadrian target:
* `binary-dist-dir-cross`: Build a cross compiler bindist (compiler =
stage 1, libraries = stage 2)
This commit also contains various changes to make stage2 compilers
feasible.
-------------------------
Metric Decrease:
LinkableUsage02
ManyAlternatives
ManyConstructors
MultiComponentModulesRecomp
MultiLayerModulesRecomp
RecordUpdPerf
T10421
T12150
T12227
T12425
T12707
T13035
T13379
T13820
T15703
T16577
T18140
T18282
T18698a
T18698b
T18923
T1969
T20049
T21839c
T3294
T4801
T5030
T5321FD
T5321Fun
T5631
T5642
T6048
T783
T9020
T9198
T9233
T9630
T9872d
T9961
parsing001
T3064
Metric Increase:
T26989
hard_hole_fits
-------------------------
Co-authored-by: Sven Tennie <sven.tennie(a)gmail.com>
- - - - -
26fed8ab by Matthew Pickering at 2026-06-20T23:42:52+02:00
ci: Test cross bindists
We remove the special logic for testing in-tree cross
compilers and instead test cross compiler bindists, like we do for all
other platforms.
- - - - -
80c8910e by Matthew Pickering at 2026-06-20T23:42:52+02:00
ci: Introduce CROSS_STAGE variable
In preparation for building and testing stage3 bindists we introduce the
CROSS_STAGE variable which is used by a CI job to determine what kind of
bindist the CI job should produce.
At the moment we are only using CROSS_STAGE=2 but in the future we will
have some jobs which set CROSS_STAGE=3 to produce native bindists for a
target, but produced by a cross compiler, which can be tested on by
another CI job on the native platform.
CROSS_STAGE=2: Build a normal cross compiler bindist
CROSS_STAGE=3: Build a stage 3 bindist, one which is a native compiler and library for the target
- - - - -
8215573d by Sven Tennie at 2026-06-20T23:42:52+02:00
ci: Increase timeout for emulators
Test runs with emulators naturally take longer than on native machines.
Generate jobs.yml
- - - - -
5acb7dbc by Matthew Pickering at 2026-06-20T23:42:52+02:00
ci: Javascript don't set CROSS_EMULATOR
There is no CROSS_EMULATOR needed to run javascript binaries, so we
don't set the CROSS_EMULATOR to some dummy value.
- - - - -
48345343 by Sven Tennie at 2026-06-20T23:42:52+02:00
Javascript skip T23697
See #22355 about how HSC2HS and the Javascript target don't play well
together.
- - - - -
5e44fd05 by Sven Tennie at 2026-06-20T23:42:52+02:00
Mark T24602 as fragile
It was skipped before (due to CROSS_EMULATOR being set, which changed
for JS), so we don't make things worse by marking it as fragile.
- - - - -
ab349ec2 by Sven Tennie at 2026-06-20T23:42:52+02:00
Fix T22744 for GHCJS
In fact, this test needs Template Haskell, not necessarily an
interpreter.
- - - - -
c73352d8 by Sven Tennie at 2026-06-20T23:42:52+02:00
haddock-test: fix GHCJS haddock test failures
Add --ghc-pkg-path flag support so haddock test runner can find
cross-prefixed ghc-pkg (e.g. javascript-unknown-ghcjs-ghc-pkg) which
is not on $PATH in cross install directories.
Skip haddockHtmlTest on GHCJS: Threaded.hs uses forkOS in a TH splice,
which GHCJS RTS doesn't support. Mark with js_skip in all.T.
- - - - -
5e814e76 by Andreas Klebinger at 2026-06-22T23:00:24-04:00
compiler: Deduplicate hscTidy
This function was accidentally duplicated during a refactor.
Fixes #27351
- - - - -
473b97eb by sheaf at 2026-06-22T23:01:22-04:00
Avoid mkTick in Core Prep breaking ANF (part II)
Hotfix for 2f9579765f55b3920ceb2e04995ff41a9d0e2d4e fixing a small
oversight in the call to tickTickedExpr from mkTick, in which we
improperly recursively called mkTick without passing on the preserve_anf
flag.
Fixes #27386
- - - - -
9284a1f7 by Simon Hengel at 2026-06-23T05:55:33-04:00
Don't use global variables to address concurrency bugs! (fixes #27234)
This was originally introduce with
88f38b03025386f0f1e8f5861eed67d80495168a to address #17922.
In this specific case a better fix would have been to synchronize on
stderr:
withHandle_ "stderrSupportsAnsiColors" stderr $ \ _ -> do
...
But apparently the dependency on `terminfo` was removed in
32ab07bf3d6ce45e8ea5b55e8095174a6b42a7f0, preventing #17922 in the first
place.
- - - - -
44309cd3 by Alan Zimmerman at 2026-06-23T05:56:20-04:00
EPA: remove LocatedL / SrcSpanAnnL and LocatedLI / SrcSpanAnnLI
This is part of a refactor towards only having LocatedA / SrcSpanAnnA
It removes the stated items, but has to add back one for BooleanFormula,
LocatedBF / SrcSpanAnnBF
This commit also use the HsConDetails RecCon extension point to
capture the braces in a record constructor
- - - - -
2f6a5534 by Simon Jakobi at 2026-06-23T15:46:20+02:00
Add -dstable-core-dump-order for stable Core dump ordering (#27296)
The order of top-level bindings in Core dumps (-ddump-simpl etc.) is the
compiler's Unique-sensitive internal processing order, so an unrelated
upstream change can reorder them and defeat a textual diff of two dumps.
This adds an opt-in flag -dstable-core-dump-order that reorders the
top-level bindings of dumps routed through dumpPassResult into a stable,
Unique-independent order, so two dumps line up across rebuilds. See
Note [Stable Core dump order] in GHC.Core.Ppr for the sort key and its
rationale.
Adds tests T27296 (binders GHC emits in non-source order by default,
asserted to come out stably ordered under the flag) and T27296b (an
untidied -ddump-float-out dump pinning the ordering of the anonymous lvl
floats by literal value).
Co-Authored-By: Claude Opus 4.8 <noreply(a)anthropic.com>
- - - - -
141986e3 by mangoiv at 2026-06-24T15:51:14-04:00
compiler: refactor error reporting code for ExplicitLevelImports
Refactors error reporting code for ExplicitLevelImports to pass in a
RdrName and a GlobalReaderElt to be able to report errors that are
faithful to the source and to more precisely distinguish between names
that are in scope from different qualifications.
Fixes #27385 and #26616
- - - - -
aa7df6b6 by Simon Hengel at 2026-06-24T15:52:18-04:00
Set GHC_VERSION when calling custom pre-processors (see #25952)
(so that pre-processors can emit backwards compatible code)
- - - - -
a9e494f2 by Simon Hengel at 2026-06-24T15:54:08-04:00
Add a flag to control GHCi specific error hints (close #27409)
- - - - -
a805b2a2 by Simon Hengel at 2026-06-24T15:55:20-04:00
Reference correct package in error messages for reexported modules
(fixes #27417)
- - - - -
f235d183 by Simon Jakobi at 2026-06-25T05:51:18-04:00
Add explicit setBit/clearBit/complementBit for instance Bits Integer (#21176)
The default setBit, clearBit, and complementBit methods allocate
intermediate Integers per call. Define them explicitly via the new
integerSetBit[#], integerClearBit[#] and integerComplementBit[#], built
on the BigNat# primitives, which avoid those allocations. Allocation is not
eliminated entirely -- the negative (IN) cases would need in-place mutation,
which is left as future work.
The default methods constant-folded on literal arguments via the
integerOr/integerAnd/integerXor rules, which fold literal Integers of any
size. The explicit functions have no such rule, so they (their Word-argument
wrappers, and the Bits Integer methods) are marked INLINE to expose the
underlying primops to the simplifier; see Note [INLINE for constant folding
of bit operations]. This restores folding only on the small-int (IS) path --
large literal Integers (IP/IN) are no longer constant-folded, a minor
regression for that case. T8832 covers the IS-path folding.
The new golden-output test T21176 checks all three operations against the
default implementations across the sign/size boundaries, recording each
result plus its integerCheck validity. The base and ghc-bignum interface-
stability export goldens gain the new functions.
The main changelog entry lives in changelog.d under a new ghc-internal
section (renamed from ghc-prim).
CLC proposal: https://github.com/haskell/core-libraries-committee/issues/423
Co-Authored-By: Claude Opus 4.7 <noreply(a)anthropic.com>
- - - - -
202ed264 by Marc Scholten at 2026-06-25T05:52:21-04:00
haddock: use Text in documentation pipeline
This patch moves Haddock's documentation pipeline from String to Text
where the data is already textual. It avoids repeated conversions while
keeping the existing decoding behavior for invalid UTF-8 docstring
chunks.
The main changes are:
* Render and carry docstrings as Text in Haddock-facing paths.
* Use the Binary Text instance from GHC.Utils.Binary for Haddock
interface files, and bump the Haddock binary interface version.
* Add a FastString HTML instance so XHTML rendering avoids
intermediate String allocation.
* Keep HsDocStringChunk decoding lenient, matching the previous
unpackHDSC behavior on invalid UTF-8 input.
* Update the xhtml submodule to 3000.4.1.0, which contains the
apostrophe escaping fix used by the Haddock test output.
Co-authored-by: copilot-swe-agent[bot] <198982749%2BCopilot(a)users.noreply.github.com>
Co-authored-by: Claude Opus 4.5 <noreply(a)anthropic.com>
Assisted-by: Codex <codex(a)openai.com>
- - - - -
a72ff58f by mangoiv at 2026-06-25T05:53:07-04:00
compiler: rename ZonkAny to UnusedType and add pretty printing logic
ZonkAny is a hard to understand name for users who do not know how the
compiler works internally. Additionally, it is confusing that ZonkAny,
while being a concrete type *represents* a meta variable, espeically in
the compiler output.
This patch changes the name of ZonkAny to UnusedType which is closer to
its intended semantics and adds special pretty printing logic to display
this type in the same fashion the compiler displays meta variables in
other places, whenever they leak from the implementation to the user.
It also exports the type from ghc-internal:GHC.Internal.Types in order
to expose documentation.
Fixes #27390
Co-Authored-By: Sam Derbyshire <sam.derbyshire(a)gmail.com>
- - - - -
6813f002 by Simon Jakobi at 2026-06-26T04:51:47-04:00
Reg.Linear: drop Platform argument from most FR (FreeRegs) methods
The FR class has one instance per CPU architecture, so any
architecture-constant information its methods derived from the Platform
argument can instead be baked into the instance. This removes the now
needless Platform argument from frAllocateReg, frGetFreeRegs and
frReleaseReg.
frInitFreeRegs keeps its Platform argument: the initial allocatable set is
genuinely platform-dependent, see Note [Aarch64 Register x18 at Darwin and
Windows].
Fixes #26665
Co-Authored-By: Claude Opus 4.8 <noreply(a)anthropic.com>
- - - - -
3b2a9409 by Zubin Duggal at 2026-06-26T04:52:39-04:00
testsuite: Report fragile failures as skipped in JUnit output
- - - - -
27463426 by Rodrigo Mesquita at 2026-06-26T20:54:58-04:00
perf: Share Module in Iface Symbol Table
This commit modifies the structure of the serialized `SymbolTable Name`
to then re-use and share the `Module` (both on disk and in memory) across
all `Name`s from the same module.
The new structure looks like:
<total name count>
$modules.size
for (mod, names) in $modules:
$mod
$names.size
for table_ix, occ in $names
$table_ix
$occ
i.e. we put the module just once, followed by all names in that module.
When deserializing, we deserialize the module just once, and all the
following `Name`s are constructed with a pointer to that same decoded
`Module`.
In `hoogle-test`, we must use `DNameEnv` rather than `Map Name`,
otherwise the output fixities order was susceptible to changes in the
uniques assigned to each Names, which is not stable.
Fixes #27401
-------------------------
Metric Decrease:
InstanceMatching
LinkableUsage01
LinkableUsage02
hard_hole_fits
-------------------------
- - - - -
412f1675 by Simon Hengel at 2026-06-26T20:55:41-04:00
Rename `MCDiagnostic` to `InternalMCDiagnostic`
`MCDiagnostic` is meant to be used for compiler diagnostics.
Any code that creates `MCDiagnostic` directly, without going through
`GHC.Driver.Errors.printMessage`, sidesteps `-fdiagnostics-as-json` (see
e.g. !14616, !14475, !14492 !14548).
To avoid this in the future, this change more narrowly controls who
creates `MCDiagnostic` (see #24113).
- - - - -
6f212121 by Facundo Domínguez at 2026-06-26T20:56:27-04:00
Encapsulate options of occurAnalysePgm in a record
- - - - -
adfbb179 by Facundo Domínguez at 2026-06-26T20:56:27-04:00
Allow to configure the occurrence analyser to retain some dead bindings
This is needed by plugins that are the only consumers of a binding which
is otherwise unused in the program.
See Note [Controlling elimination of dead bindings in occurrence analysis]
added in this commit, or
https://gitlab.haskell.org/ghc/ghc/-/issues/27240 for more discussion.
- - - - -
c745b11f by Copilot at 2026-06-26T20:56:27-04:00
Address documentation feedback
- - - - -
2c2a4a2a by Copilot at 2026-06-26T20:56:27-04:00
Keep the imp_rules parameter of occurPgmAnalysePgm and add occ_opts to OccEnv
- - - - -
e2262b0e by Copilot at 2026-06-26T20:56:27-04:00
Strengthen T27240.hs with a binding that should be removed
- - - - -
5f9d9268 by Copilot at 2026-06-26T20:56:27-04:00
Move the reference #27240 to a related paragraph
- - - - -
d86d2644 by Simon Hengel at 2026-06-26T20:57:10-04:00
Remove deprecated flag `-ddump-json` (see #24113)
This was first deprecated in 9.10.1.
- - - - -
3b15ff03 by Simon Jakobi at 2026-06-27T18:48:34+02:00
Tweak mk_mod_usage_info
* Use O(log n) `elemModuleEnv` instead of O(n) `elem` to filter the
direct imports.
* Use `nonDetModuleEnvKeys` to avoid sorting the ent_map keys twice.
* Prepend the presumably shorter list when creating all_mods with
`(++)`. Actually this eliminates the `(++)` entirely, as it seems to
fuse with the `filter` expression.
As a result there is a tiny speed-up when generating the .hi-files for
modules with many imports.
None of the changes affect compilation determinism as the module list
is explicitly sorted to ensure a canonical order.
- - - - -
2d0fd154 by Alan Zimmerman at 2026-06-29T11:44:00-04:00
EPA: Remove LocatedC / SrcSpanAnnC
This is part of a cleanup of the zoo of
SrcSpanAnnXXX types for exact print annotations.
This one removes SrcSpanAnnC used for storing exact print annotations
for contexts. It replaces it with an explicit `HsContext` data type
that carries the annotations and the context.
So, replace
type HsContext pass = [LHsType pass]
with
type HsContext pass = HsContextDetails pass (LHsType pass)
data HsContextDetails pass arg
= HsContext
{ hsc_ext :: !(XHsContext pass)
, hsc_ctxt :: [arg]
}
| XHsContextDetails !(XXHsContextDetails pass)
We need the parameterised HsContextDetails because it is used both for
HsQual carrying 'LHsExpr p' and "normal" contexts carrying 'LHsType p'.
- - - - -
cca0d589 by Luite Stegeman at 2026-06-30T13:33:40-04:00
rts: handle large AP closures in compacting GC
The function update_fwd_large in the compacting GC could run into
an unexpected object with the following error:
internal error: update_fwd_large: unknown/strange object 24
Closure type 24 is the AP closure, which was not handled in
upd_fwd_large. This patch adds handling them.
fixes #27434
- - - - -
42935858 by Luite Stegeman at 2026-06-30T13:33:40-04:00
testsuite: use compacting_gc way instead of hardcoding +RTS -c
- - - - -
bf7b5ce6 by Alan Zimmerman at 2026-06-30T13:34:23-04:00
EPA: Remove LocatedLW from LStmtLR
HsDo already had its XDo extension point for an
AnnList, which also appeared in LocatedLW.
So we remove the redundant one and use the one inside HsDo
as originally intended.
Also delete LocatedLC/LocatedLS as they were unused
- - - - -
d7cfea49 by Recursion Ninja at 2026-06-30T21:37:12-04:00
Decoupling 'L.H.S' from 'GHC.Types.SourceText'
* Migrated 'IntegralLit' to 'L.H.S.Lit'.
* Migrated 'FractionalLit' to 'L.H.S.Lit'.
* Migrated 'StringLiteral' to 'L.H.S.Lit'.
* Added TTG extension points to the types above.
* Added nice export list to 'GHC.Hs.Lit'.
* Added 'rnOverLitVal' and 'tcOverLitVal' functions to 'GHC.Hs.Lit'.
* Added instance 'Anno (StringLiteral (GhcPass p)) = SrcSpanAnnN'
* Moved [Notes] about 'SourceText' from 'L.H.S.*' to 'GHC.*'.
* Removed all references to 'SourceText' from 'L.H.S'.
* Removed the trailing comma record field from 'StringLiteral'
* Renamed exported functions for nomenclature consistency.
* Deprecated the renamed functions
Fixes #26953
- - - - -
a1f2558b by Recursion Ninja at 2026-06-30T21:37:12-04:00
Monomorphising GHC pass parameters where appropriate
- - - - -
7bf9e3c5 by Teo Camarasu at 2026-06-30T21:38:03-04:00
Make Q abstract
This patch aims to clearly demarcate the internal and external interfaces
of Q.
In the past the `Quasi` typeclass was both part of the external,
public-facing interface, and was used to give the implementation of `Q`.
Now we separate out these two distinct roles. `Quasi` continues to exist
in the public interface, but we introduce a new `MetaHandlers` type,
which is equivalent to `Dict Quasi`.
`Q a` is now defined to be `MetaHandlers -> IO a`, and, crucially,
the constructor and the new `MetaHandlers` type are not exposed from the
public interface.
This gives us the ability to vary the interface on the GHC side without
forcing a breaking change on the `template-haskell` side.
Similarly `template-haskell` has more freedom to change the `Quasi`
typeclass without needing any changes in `lib:ghc`.
Implements https://github.com/ghc-proposals/ghc-proposals/pull/700
Resolves #27341
- - - - -
4262af36 by L0neGamer at 2026-06-30T21:38:56-04:00
generically defines mconcat in terms of internal type's Semigroup instance
add changelog entry
use simpler definition for mconcat
`nonEmpty` isn't available yet; inline branches in case
add test case
fixup generically defines mconcat in terms of internal type's Semigroup instance
add comment on Generically and deriving mishaps
swap mconcat to foldr version
add some strictness testing for mconcat
add to `base` changelog entry
- - - - -
e22ad997 by Cheng Shao at 2026-06-30T21:39:43-04:00
hadrian/rts: fix unregisterised build for gcc 15+
This patch fixes unregisterised build for gcc 15+:
- Pass -optc-Wno-error in hadrian when +werror enables -optc-Werror,
see added comment for details.
- For RTS functions that the codegen would emit calls, ensure their
real prototype is hidden when the header is included in .hc fies
(IN_STG_CODE), and the dummy prototype is provided to match the EFF_
convention.
In the future we should get rid of EFF_ (#14647) and remove these
hacks, but for now this patch makes unregisterised work again on newer
toolchains. Fixes #27404.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
3f00f234 by Cheng Shao at 2026-06-30T21:40:32-04:00
compiler: fix missing handling of CmmUnsafeForeignCall node in LayoutStack
This patch fixes missing handling of `CmmUnsafeForeignCall` middle
node in the `LayoutStack` pass.
Before proc-points splitting, this pass computes liveliness of local
registers, and spills those alive across a Cmm native call onto the
stack. It need to traverse all middle nodes in each block and check
whether a local register is an assignee, if so then the previous
mapping in `sm_regs` is invalidated and needs to be dropped. However,
it didn't handle `CmmUnsafeForeignCall` node which may also assign to
a local register. When proc-points splitting is enabled, this can
produce an invalid basic block that doesn't properly backup the
updated local register to the stack before doing a Cmm call, resulting
in completely invalid runtime behavior.
The patch also adds a `T27447` regression test. With no-TNTC or with
LLVM backend, without the fix the test case would output a stale
0x1111111111111111 value, instead of the expected 0x2222222222222222
output.
Fixes #27447.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
701088db by Ben Gamari at 2026-07-01T10:34:03-04:00
gitlab-ci: Drop vestigial references to make build system
- - - - -
62d54a53 by Ben Gamari at 2026-07-01T10:34:03-04:00
gitlab-ci: Add support for running specifying a job's testsuite ways
- - - - -
7f97ac2c by Ben Gamari at 2026-07-01T10:34:03-04:00
gitlab-ci: Run llvm testsuite ways in llvm jobs
Addresses #25762.
- - - - -
7ea75116 by ARATA Mizuki at 2026-07-01T10:34:03-04:00
testsuite: Add normalise_ddump_deriv setup function
Some tests check the result of -ddump-deriv, which may contain INLINE pragmas depending on optimization flags.
With normalise_ddump_deriv setup function, INLINE pragmas are stripped off.
- - - - -
c7a8199f by ARATA Mizuki at 2026-07-01T10:34:03-04:00
testsuite: Use -dsuppress-idinfo to make tests more robust
Previously, T18052a and T21755 were failing on 'optasm' and 'optllvm' ways because of visibility of unfoldings.
- - - - -
a12122e5 by ARATA Mizuki at 2026-07-01T10:34:03-04:00
testsuite: Use a trick to keep large objects alive
Previously, T17574 and T19381 were failing on 'optasm' and 'optllvm' ways because of compiler optimizations.
Change them to use NOINLINE to prevent unwanted optimizations.
- - - - -
1a95b327 by ARATA Mizuki at 2026-07-01T10:34:03-04:00
testsuite: Only run T24224 in 'normal' way
This test is a frontend-only one and breaks if optimizations are enabled.
- - - - -
8abea737 by ARATA Mizuki at 2026-07-01T10:34:03-04:00
testsuite: Ignore T18118's stderr
When optimizations are enabled, the compiler emits a warning (You cannot SPECIALISE ...).
The message is not important, so ignore it.
- - - - -
9453a722 by ARATA Mizuki at 2026-07-01T10:34:03-04:00
testsuite: Mark T816 and tc216 broken with optimizations
These tests are about type checking, so we should not care too much if they are broken with optimizations.
See #26952
- - - - -
0aef9ec0 by Ben Gamari at 2026-07-01T10:34:03-04:00
testsuite: ds014 is not longer broken
It now appears to pass in the ways it was marked as broken in.
Closes #14901.
- - - - -
4692d1e4 by Ben Gamari at 2026-07-01T10:34:03-04:00
testsuite: Only run stack cloning tests in the normal way
These are too dependent upon code generation specifics to pass in most
other ways.
- - - - -
c154df26 by ARATA Mizuki at 2026-07-01T10:34:03-04:00
testsuite: Update options_ghc_fbyte-code
The `-fbyte-code` option used to be overriden by `-fllvm` but it is no longer true since !14872 was merged.
I updated the test to accept the new behavior.
Closes #27049
- - - - -
5d8bb7b5 by ARATA Mizuki at 2026-07-01T10:34:03-04:00
testsuite: Only run T22744 in 'normal' way
This test takes a long time on optimized ways.
- - - - -
d1e74c8e by ARATA Mizuki at 2026-07-01T10:34:03-04:00
testsuite: Disable tests that use -finfo-table-map on llvm ways
Currently, -finfo-table-map does not work with -fllvm. See #26435
- - - - -
3bf38c84 by ARATA Mizuki at 2026-07-01T10:34:03-04:00
testsuite: Don't run T24726 on optimized ways
If optimizations are enabled, the rewrite rule just fires and -drule-check will report nothing.
- - - - -
e4eef116 by ARATA Mizuki at 2026-07-01T10:34:03-04:00
testsuite: Use -fno-unoptimized-core-for-interpreter when running LinkableUsage01/02
Optimizations for the bytecode interpreter are considered experimental, and need a flag to be enabled.
- - - - -
234a9872 by ARATA Mizuki at 2026-07-01T10:34:03-04:00
testsuite: Suppress unwanted optimizations on T25284
- - - - -
99a2af2f by ARATA Mizuki at 2026-07-01T10:34:03-04:00
testsuite: Don't run stack_big_ret with optimizations
Stack layout may change with optimizations enabled.
- - - - -
04c836df by ARATA Mizuki at 2026-07-01T10:34:04-04:00
testsuite: Mark memo001 broken on optimized ways
See #27396
- - - - -
1a8a24f4 by ARATA Mizuki at 2026-07-01T10:34:04-04:00
testsuite: Mark syn-perf broken on optimized ways
See #27398
- - - - -
40412093 by Duncan Coutts at 2026-07-01T10:34:50-04:00
Add a test for thread scheduler fairness
It also tests that the interval timer and context switching works.
We also test that fairness is lost when the context switching interval
is too coarse for the duration of the test.
We add this test before doing surgery on the interval timer, so we have
decent coverage.
- - - - -
3f34d557 by Duncan Coutts at 2026-07-01T10:34:50-04:00
Make exported stop/startTimer no-ops, and rename internal functions
Specifically, internally rename:
stop/startTimer to pause/unpauseTimer
stop/startTicker to pause/unpauseTicker
and keep stop/startTimer as exported functions, but now as no-ops.
In the past the stop/startTicker actions were used incorrectly as if
they were synchronous, which they are not. See issue #27105. We now
document pause/unpackTicker as being async and not to be used for the
purpose of concurrency safety.
The existing stop/startTimer (note Timer not Ticker, the Timer calls the
Ticker!) are also exported from the RTS as a public API. This was
historically because the ticker used signals and it was important to
suspend the timer signel over a process fork. So these functions were
exported to be used by the process and unix libraries.
We cannot just remove the RTS exports, but we now make them no-ops, and
they can be removed from the process and unix library later. This
was already documented in a changelog.d entry no-more-timer-signal but
due to changes during the MR process the change to make stop/startTicker
into no-ops didn't make it into the earlier MR.
- - - - -
02e84e5f by Duncan Coutts at 2026-07-01T10:34:51-04:00
Make exitTicker/exitTimer unconditionally synchronous
We never use them asynchronously, and we should never need to do so.
And update some related comments.
- - - - -
13db6a72 by Duncan Coutts at 2026-07-01T10:34:51-04:00
posix ticker: update and improve comments on (un)pause and exit
Clarify what is async vs sync.
- - - - -
43d9a07d by Duncan Coutts at 2026-07-01T10:34:51-04:00
posix ticker: split out ppoll/select helper functions
Move the #ifdefs out of the main code body by introducing local helper
functions and types, which themselves have two implementations (with a
common API) based on ppoll or select.
This helps improve clarity/readability.
- - - - -
a5491baa by Duncan Coutts at 2026-07-01T10:34:51-04:00
posix ticker: improve the implementation
The existing implementation supported pausing and exiting, with the
implementation of pausing reling on a mutex and condition variable.
It needed to check the pause and stop shared variables on every
iteration. It relies on ppoll or select, to wait on the timeout and also
wait on an interrupt fd. The interrupt fd was only used for prompt
exit/shutdown, and not for pausing or other notification. The pause only
needed a lock and a memory operation, but the pause was not prompt. The
resume used a lock, and signaling a cond var.
The new implementation uses a somewhat more regular design: every
notification is done by setting a shared variable and
interrupting/notifying the ticker via the fd. The ticker thread does not
need to check any shared variables on normal timer expiry, only when it
recevies notification. This may be a micro-optimisation, but the tick
occurs 100 times a second by default so any improvements in the hot path
are amplified. When the ticker thread does receive notification it can
check the various shared variables and update its local state. The
blocking relies on using ppoll/select but without a timeout. This avoids
the condition var and also allows further notifications when paused
(also used for unpausing).
This design can be extended with further notification types if needed by
using and checking further shared vars (or making existing shared vars
an enum or counter). This may be used in future for additional
notifications to the ticker thread. This will likely be used to proxy
wakeUpRts from a single handler context for example. And this approach,
avoiding mutexes, is compatible with use from signal handlers.
So overall, it's:
* slightly simpler / more regular;
* easier to extend with additional notifications;
* probably slightly more efficient (but a micro-optimisation);
* and supports calling notification from signal handlers
- - - - -
5b20821e by Duncan Coutts at 2026-07-01T10:34:51-04:00
posix ticker: further minor local renaming for code clarity
Improve the clarity with better choice of names for several local vars
and function.
- - - - -
1f3ec5e0 by Duncan Coutts at 2026-07-01T10:34:51-04:00
win32 ticker: split out local helper functions
- - - - -
596e7307 by Duncan Coutts at 2026-07-01T10:34:51-04:00
win32 ticker: provide guarantee about concurrency and idempotency
Use a lock to ensure pause/unpause can be used concurrently. Use a
paused variable, protected by the lock, to ensure that pause and unpause
are both idempotent. This is what the portable API expects.
- - - - -
1870edd7 by Duncan Coutts at 2026-07-01T10:34:51-04:00
win32 ticker: make the initial tick be after one wait interval
There is no need to tick immediately. This is consistent with the
posix implementation.
- - - - -
7c15ab5b by Duncan Coutts at 2026-07-01T10:34:51-04:00
ticker: remove now-unnecessary layer of enable/disable
There was an atomic variable used to block *part* of the actions of the
tick handler. This still did not make stopTimer synchronous, even for
the part of the the handle_tick actions it covered. It also added a more
expensive (sequentuially consistent) atomic operation in the hot path
for the handle_tick action, whereas our new design requires no atomic
ops at all.
Now that we have eliminate the need for synchronous stop/startTicker,
we don't need this not-quite-working-anyway atomic protocol. The new
pause/unpauseTicker is explicitly asynchronous and idempotent.
- - - - -
8585f8cb by Duncan Coutts at 2026-07-01T10:34:51-04:00
ticker: add TODOs about issue #27250: too much being done from handle_tick
The handle_tick should not perform I/O, block, perform long-running
operations or call arbitrary user code. Unfortunately, everything to
do with the eventlog (at the moment) falls into all those categories.
- - - - -
6e381626 by Duncan Coutts at 2026-07-01T22:29:55+01:00
Adjust releaseCapability_ precondition to allow cap->running_task == NULL
There are two use cases for releaseCapability_:
1. The current Task (cap->running_task) releases the Capability.
The Capability is marked free, and if there is any work to do,
an appropriate Task is woken up.
2. There is no current task (cap->task == NULL), and thus the
Capability is idle, and we want to wake up an idle Task to animate
the Capability. This case uses always_wakeup.
Currently, the precondition for releaseCapability_ is
cap->running_task != NULL
and so the 2nd use cases have to set cap->running_task (which is then
immediately overwritten) just to satisfy the precondition. See the
use cases in sendMessage and prodCapability.
So we can relax the precondition to be:
cap->running_task != NULL || always_wakeup
so that in the always_wakeup case, we say it is ok for the
cap->running_task to be NULL.
This lets us simplify sendMessage and prodCapability. In particular it
will allow prodCapability to not need a Task parameter.
The ulterior motive for all this is that I want to be able to call
prodCapability from an OS thread that is not itself a Task, in persuit
of issue #27086: disentangle I/O managers from wakeUpRts. The most
straightforward way to wake the RTS is using prodCapability, but the
context in which we will need to do that are threads that are not Tasks.
- - - - -
89404ebc by Duncan Coutts at 2026-07-01T22:29:55+01:00
prodCapability no longer needs to take a Task param
Now that releaseCapability_ can accept cap->running_task == NULL then it
is no longer necessary for prodCapability to require a Task.
- - - - -
4e60c5f6 by Duncan Coutts at 2026-07-01T22:29:56+01:00
Define prodOneCapability
There was an existing declaration for this in the header file, but no
definition.
Similarly, there is a declaration for prodAllCapabilities but no
definition, and we don't need it, so remove the declaration.
- - - - -
2527026f by Duncan Coutts at 2026-07-01T22:29:56+01:00
Add a wakeUpRtsViaTicker feature to the posix ticker
It proxies a call to wakeUpRts, but crucially, this can be called from
a signal handler context. It will be used for ctl-c handling.
- - - - -
aa5a03a5 by Duncan Coutts at 2026-07-01T22:29:56+01:00
Change how wakeUpRts works
Previously it would call wakeupIOManager to get a capability to wake up
and run. This works but it entangles the I/O managers with unrelated
features: ctl-c handling and idle gc (the two features that use wakeUpRts).
The reason it used wakeupIOManager is that this action is safe to use
from a posix signal handler, since it just posts bytes to a pipe.
Otherwise the more direct approach (used e.g. by sendMessage when the
target capability is idle) is to use releaseCapability. But that uses
condition variables and mutexes, which are not safe to use from within a
signal handler.
So instead of entangling the (multiple) I/O managers with this, we make
wakeUpRts use the direct approach (using prodOneCapability). On win32
the ctl-c console handler can call wakeUpRts directly, since it is
called in a proper thread. On posix, to deal with the signal handler
problem, we make the signal handler ask the ticker thread to proxy the
call to wakeUpRts, since the ticker thread is also a proper thread.
This will allow the I/O managers to no longer be concerned with this.
This is good because there are many I/O managers (and they're
complicated), but there is (on posix) only one ticker implementation. So
this is an overall reduction in coupling and complexity.
Fixes issue #27086
- - - - -
c6d53c16 by sheaf at 2026-07-02T21:35:44-04:00
Test driver: normalise line numbers into libraries
When comparing the stdout of tests that print out callstacks, we can't
rely on the stability of exact line:column spans pointing into libraries
(e.g. ghc-internal), as any change (such as adding a comment) can change
them.
This commit addresses this by normalising away line:column in callstacks,
but only when those point into internal libraries. We don't do this in
general, as the exact span might be important to the test (e.g. for a
span within the test module itself).
Fixes #27387
- - - - -
81ee62e0 by Alan Zimmerman at 2026-07-02T21:36:33-04:00
EPA: Remove LocatedLW from MatchGroup
This is the last usage of LocatedLW / SrcSpanAnnLW
- - - - -
925959db by Recursion Ninja at 2026-07-04T04:14:12-04:00
Decoupling 'L.H.S' from 'GHC.Hs.Doc'
* Migrated 'GHC.Hs.Doc' and 'GHC.Hs.DocString' AST defintions from 'GHC.*' namespace,
to new 'Language.Haskell.Syntax.Doc' module in the 'L.H.S' "namespace."
* Updated 'HsDocString to be TTG-parameterised as 'HsDocString pass'.
* Added 'GHC.Hs.Extension.Pass': splits 'GhcPass'/'Pass' and all 'HsDocString'
TTG instances out of 'GHC.Hs.Extension', which re-exports it unchanged
(this is backwards compatible and prevents the introduction of a boot file).
* Deleted 'GHC.Hs.Doc.hs-boot'; removed all 'L.H.S.*' imports of 'GHC.Hs.Doc'.
* Updated 'GHC.Hs.DocString' to be TTG pass-parameterised throughout; moved
'mkHsDocStringChunk'/'unpackHDSC' here (require 'GHC.Utils.Encoding').
* Split 'GHC.Rename.Doc.rnHsDoc' from 'rnHsDocIdentifiersOnly'.
* Updated parser, renamer, typechecker, HIE, and exact-print for new types.
* Added 'HsDocString' TTG instances for 'DocNameI' to 'Haddock.Types'.
* Killed the last module loop between GHC.* and LHS.*.
- Only edges from LHS.* to GHC.Data.FastString now!
Resolves #26971
- - - - -
b7e24044 by mangoiv at 2026-07-04T04:14:56-04:00
ci: retry fetching test metrics
Retry fetching test metrics to make the CI not fail if the services is
temporarily unavailable
- - - - -
4180af3f by Zubin Duggal at 2026-07-04T04:15:38-04:00
Bump semaphore-compat submodule to 2.0.1
This versions includes some cruicial fixes for darwin
- - - - -
242d4317 by sheaf at 2026-07-04T04:16:19-04:00
Remove outdated comment in GHC.Data.ShortText
There was a long comment in GHC.Data.ShortText about a workaround that
was necessary when bootstrapping with GHC 9.2 and below. The actual
logic has since been dropped, but the comment remained. This commit
removes the vestigial comment.
- - - - -
9b714c4c by Zubin Duggal at 2026-07-05T09:40:36+05:30
CorePrep: Don't speculatively evaluate bindings that we have already discovered to be absent
In #25924, we segfault because speculation forces a projection out of a RUBBISH dictionary
(which we generated because it absent).
Solution: Don't speculate on bindings we already know are absent.
Fixes 25924
- - - - -
4a59b3ee by Zubin Duggal at 2026-07-05T09:40:36+05:30
Don't make absent fillers for terminating types
In #25924 we discovered that we could speculatively evaluate an absent filler
for a dictionary, and project a field (a superclass selector) out of it,
resulting in segfaults.
Solution: Never make an absent filler or rubbish literal for a terminating type
like a dictionary. mkAbsentFiller returns Nothing for isTerminatingType, so
worker/wrapper and the specialiser keep the real argument instead.
Some small metric decreases because we do a little less work in the
simplifier now.
Metric Decrease:
T9872a
T9872b
T9872c
TcPlugin_RewritePerf
- - - - -
383ddcd4 by Alan Zimmerman at 2026-07-06T07:08:16-04:00
EPA: Move the 'where' annotation for PatSynBind
This allows us to move it out of the MatchGroup exact print annotation
too
- - - - -
66d1a5d5 by fendor at 2026-07-07T16:57:56-04:00
Add 'backendInfoTableMapValidity' backend predicate
Check whether the backend supports the `-finfo-table-map` flag and
ignore it otherwise.
Improve by-design documentation of `backendCodeOutput`.
`Backend` is **abstract by design**. Make this clearer in
`backendCodeOutput` which is incorrectly being used as a proxy for
`Backend`.
Instead, define the desired property predicates in GHC.Driver.Backend
In the process, make `backendCodeOutput` total.
- - - - -
74f1071d by fendor at 2026-07-07T16:57:56-04:00
Add failing test for `-finfo-table-map` and bytecode backend
If you compile a module using the bytecode backend, with
-finfo-table-map, then the info table map doesn't get populated for the
module.
This is because the -finfo-table-map code path is implemented mostly in
the StgToCmm phase which isn't run when creating bytecode.
Ticket #27039
- - - - -
28d63bca by mangoiv at 2026-07-07T16:59:16-04:00
ci: don't fail nightly if there have been no changes that night
Fixes #27127
- - - - -
4ebfc478 by Rodrigo Mesquita at 2026-07-08T04:47:53-04:00
ttg: Using ShortText over FastString in the AST
To make the AST independent of GHC, this commit replaces usages of
`FastString` with `HText` in the AST, killing the last edge from
Language.Haskell.* to GHC.* modules.
Even though we /do/ want to use FastStrings in general -- critically in
Names or Ids -- there is no particular reason for the FastStrings that
occur in the AST proper to be FastStrings. Strings in the AST are
typically unique and don't benefit particularly from being interned
FastStrings with Uniques for fast comparison.
`HText` is a type synonym for `ShortText` which uses GHC's Modified
UTF-8 encoding exclusively.
Modified UTF-8 must be used to represent the Haskell AST because the
Haskell Report allows surrogate code points. `Data.Text.Text` functions
use Standard UTF-8 which replace surrogates with a placeholder value,
thus `Data.Text.Text` is unsuitable for AST strings. See the
`Language.Haskell.Syntax.Text` module header for more details.
Final progress towards #21592
Closes #21628
- - - - -
d910b353 by Simon Peyton Jones at 2026-07-08T04:48:36-04:00
Update equality-type documenation in GHC.Builtin.Types.Prim
Fix #27466
- - - - -
b2530542 by Simon Peyton Jones at 2026-07-08T04:48:36-04:00
Honour -dsuppress-coercions in GHC.Core.TyCo.pprCo
Fixes #27467
- - - - -
9a73179a by Facundo Domínguez at 2026-07-08T04:49:26-04:00
Add item to MR checklist asking to squash fixup commits after approval
The checklist has an item that reads
All commits are either individually buildable or squashed.
This item could be checked immediately after sending the merge request
though. If reviewers ask for amends later on, and the author amends
the merge request, there was no item that would remind the contributors
to squash the fixup commits before landing.
This commit adds a new item
After all approvals and before landing: all fixup commits are squashed with their originating commits.
which should be harder to mark as done before approvals have been given.
- - - - -
ed09895d by Andreas Klebinger at 2026-07-08T16:53:27-04:00
Fix a profiling race condition resulting in segfaults.
StgToCmm: Don't assume tagged FUN closures in closureCodeBody.
When entering a closure the self/node pointer might not be tagged in
some situations when a thunk is evaluated by multiple threads.
So we most AND away the tag bits rather than subtracting an expected tag.
Apply.cmm: Fix a race condition occuring when a thunk is mutated during GC.
In stg_ap_0_fast when might need to run GC before entering a thunk. If this happens
another thread or the GC itself might mutate the closure making entering it no longer
valid. We now check for this.
Add test and changelog for #27123 fixes.
- - - - -
67c03eb2 by Cheng Shao at 2026-07-08T16:54:09-04:00
ghc-heap: fix invalid srtlen returned by peekItbl when no-TNTC
This patch fixes the no-TNTC code path of `peekItbl` so that it looks
at the right memory address when reading the `srt` field from the
`StgInfoTable_` struct. Also adds a `T27465` regression test that
reproduces the bug on no-TNTC builds before the fix. Fixes #27465.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
2ecabb4f by Zubin Duggal at 2026-07-09T09:23:25-04:00
hadrian: binary-dist-dir should not be the default target
Revert behaviour to pre 23c9b6c392f52ec9d7a8618b204ff6b885f5fba2
In 23c9b6c392f52ec9d7a8618b204ff6b885f5fba2, we applied the following behaviour change:
```
hadrian: Build stage 2 cross compilers
...
* hadrian: Make binary-dist-dir the default build target. This allows us
to have the logic in one place about which libraries/stages to build
with cross compilers. Fixes #24192
```
This is a major regression to development experience, a plain hadrian/build
--freeze1 now takes ages because we rebuild all docs (which need to go in the
binary dist dir).
`binary-dist-dir` is the wrong default target for regular GHC development work
Fixes #27445
- - - - -
e16388e3 by Zubin Duggal at 2026-07-09T09:23:25-04:00
.gitignore: Add the hadrian system.config introduced by commit 23c9b6c392f52ec9d7a8618b204ff6b885f5fba2
Since
commit 23c9b6c392f52ec9d7a8618b204ff6b885f5fba2
Author: Matthew Pickering <matthewtpickering(a)gmail.com>
Date: Thu Dec 21 16:17:41 2023 +0000
hadrian: Build stage 2 cross compilers
./configure produces /hadrian/cfg/system.config.{host,target}
Add these to .gitignore
- - - - -
7e8abf41 by Alan Zimmerman at 2026-07-09T09:24:12-04:00
EPA: Replace AnnListItem with simply [TrailingAnn]
Remove the unnecessary wrapper around a single field.
- - - - -
29032f17 by Zubin Duggal at 2026-07-09T09:24:58-04:00
testsuite: Keep real reason for fragile test failures
- - - - -
c34e03a7 by Zubin Duggal at 2026-07-09T09:24:58-04:00
testsuite: Fall back to the failure reason for empty JUnit bodies
- - - - -
409d40f0 by Zubin Duggal at 2026-07-09T09:24:58-04:00
testsuite: Show output diffs in JUnit output
Also refactor compare_outputs to return essentially a `Maybe Diff`
(`CompareOutput`) instead of a bool, but more pythonic. This
allows us to pass the diff through nice.
- - - - -
06fee1ab by Zubin Duggal at 2026-07-09T09:24:58-04:00
perf notes: include stat deviation and acceptance window in notes so they show up in gitlab
- - - - -
57c0f32c by mangoiv at 2026-07-10T11:08:38-04:00
driver: enable -finter-module-far-jumps by default
this fixes a compatibility bug with certain binutils/gcc versions where
we were seeing jump offset overflow errors.
This commit can probably reverted if we stop supporting the problematic
binutils/gcc verions (2.44 and 14.2, respectively)
Reolves #26994
- - - - -
4396a6f2 by Andrea Vezzosi at 2026-07-10T11:09:25-04:00
[Fix #27287] preserve ModBreaks in ModIface
- - - - -
ed261a7e by Cheng Shao at 2026-07-14T17:59:38-04:00
hadrian: fix HLS support
This patch fixes hadrian's HLS support so one can rely on HLS when
working on the hadrian codebase. Fixes #27480.
Not building/linking shared libraries for hadrian is a severely
premature optimization; this top-level setting in `cabal.project` only
affects home packages while the dependencies in the cabal store are
built with vanilla/dynamic anyway, and even adding dynamic builds to
home packages would not be costly due to cabal's usage of
`-dynamic-too`.
- - - - -
eee8ec5b by Cheng Shao at 2026-07-14T18:00:20-04:00
compiler: fix miscompiled %load_relaxed, add missing %store_relaxed
This patch fixes the %load_relaxed cmm primop compilation logic to
correctly use relaxed memory ordering, and adds the missing
%store_relaxed primop. Parsing logic of %load/%store with explicit
ordering is covered in the AtomicFetch test case. Fixes #27483.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
1718230f by Alan Zimmerman at 2026-07-14T18:01:06-04:00
EPA: Keep binds and sigs together in HsValBindsLR
We combine them into a single list for GhcPs, wrapped in the
ValBind data type, which is the bind equivalent of ValD, having
constructors for binds and sigs.
This simplifies exact print processing, especially when using it to
update the contents of local binds, as we no longer need AnnSortKey
BindTag
- - - - -
6bd1ad2a by Andreas Klebinger at 2026-07-14T18:01:49-04:00
Bump nofib submodule to account for MonoLocalBinds.
New versions of GHC enable MonoLocalBinds by default.
This breaks some of the benchmarks. I've fixed this and
this bump pulls in that fix.
- - - - -
7eb0f1c9 by Cheng Shao at 2026-07-14T18:02:31-04:00
testsuite: fix bytecodeIPE test under +ipe flavours
This patch fixes the bytecodeIPE test under +ipe flavours. It used to
fail under +ipe because the RTS is built with IPE info, then
stg_AP_info in RTS carries IPE info, so whereFrom wouldn't return
Nothing. Now the test checks IPE info of a datacon in the ghci-loaded
module which is not affected by whether the RTS is built with IPE info
or not. Fixes #27498.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
ef038aae by cydparser at 2026-07-15T04:35:41-04:00
Reduce bytes allocated for `capabilities` in RTS (fixes #27487)
In rts/Capability.c, `capabilities` is an array of pointers, but it was allocated as if it were an
array of Capability's.
- - - - -
d377e83e by Cheng Shao at 2026-07-15T04:36:27-04:00
rts: fix missing UNTAG in stg_readTVarIOzh
This patch fixes missing UNTAG on the current value closure read from
StgTVar. UNTAG is a no-op when it's stg_TREC_HEADER_info which is word
aligned; it may be a tagged closure, and reading info table from the
tagged address is an unaligned load which may cause issues on
platforms with strict alignment requirements.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
8ed03842 by Cheng Shao at 2026-07-15T04:36:27-04:00
rts: fix missing UNTAG in stg_control0zh_ll
This patch fixes missing UNTAG on the cont closure returned by
captureContinuationAndAbort. In case it's not NULL,
captureContinuationAndAbort returns a tagged StgContinuation closure,
in which case it must be untagged before accessing the
apply_mask_frame field.
In the past it worked out of luck: when apply_mask_frame was NULL then
mask_frame_offset is also 0 so the control flow didn't diverge to a
wrong path. Still, this is horribly wrong and will crash once
StgContinuation struct is refactored and fields are shuffled around.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
5aa7000a by Cheng Shao at 2026-07-15T04:37:08-04:00
compiler: fix redundant AP thunk codegen when not using -ticky-ap-thunk
This patch fixes a double negation confusion in !7525 that results in
some redundant AP thunk code generation when not using
-ticky-ap-thunk. Now, we use `stgToCmmUseStdApThunk` to indicate
whether precomputed AP thunks in the RTS should be used, which
defaults to `True`, unless `-ticky-ap-thunk` is passed.
`-finfo-table-map` now also implies `-ticky-ap-thunk`, since when
doing IPE profiling we want the generated AP thunks to be unique.
Fixes #27502.
-------------------------
Metric Decrease:
T3064
-------------------------
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
d43a7b7a by Brian McKenna at 2026-07-15T20:10:04+02:00
Strip ticks when desugaring bool guards
The special `considerAccessible` pattern was broken when compiling
with debug info. Compiling with debug info wraps expressions with
`SourceNote` ticks, which broke the internals of the
`desugarBoolGuard` function. Ticks are now ignored within this
function.
Fixes #27360
- - - - -
ede4b17b by Ben Gamari at 2026-07-15T22:59:53-04:00
base: Display ExceptionContext in WhileHandling's textual description
As originally-implemented the implementation for
`WhileHandling(displayExceptionAnnotation)` would display the
`ExceptionContext` of the exception which it carries (as this was the
behavior of `displayException`, in terms of which
`displayExceptionAnnotation` was implemented).
However, in 284ffab3 the definition of `SomeException(displayException)`
was changed to exclude the `ExceptionContext`. This means that
`WhileHandling(displayExceptionAnnotation)` fails to describe the
provenance of the exception which it captures, greatly limiting its
utility.
Return the implementation to its originally-specified behavior by
implementing `WhileHandling(displayExceptionAnnotation)` in terms of
`displayExceptionWithInfo`.
Fixes #27456.
- - - - -
0f64f348 by Cheng Shao at 2026-07-16T15:41:08+00:00
ci: add missing docker permission workaround in abi-test job
- - - - -
660cb239 by Cheng Shao at 2026-07-16T19:37:48+00:00
bindist: Fix make install -j race condition on macos/freebsd
This patch fixes make install -j race condition on macos/freebsd. BSD
install fails with EEXIST when multiple install processes concurrently
create the same prefix directory. So we add an `install_dirs`
prerequisite job that sequentially creates the directories for
subsequent jobs to work with. Fixes #27499.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
08130257 by Cheng Shao at 2026-07-16T19:37:48+00:00
ci: run bindist make install with -j
This patch makes the ci scripts run `make install` with `-j` to reduce
wall clock time when installing the bindist, see related issue for
benchmark numbers. This only affects ghc ci logic, the user-facing
default is up to distributors and is still `-j1`. Closes #27029.
- - - - -
d5ae6906 by Adam Gundry at 2026-07-17T04:57:43-04:00
Mark various language extension flags as deprecated (see #27329)
The following language extensions are now deprecated:
- AlternativeLayoutRule
- AlternativeLayoutRuleTransitional
- ParallelArrays
- PolymorphicComponents
- Rank2Types
In addition, the warning `-Walternative-layout-rule-transitional`
has been marked as deprecated, as it is emitted only under the
deprecated extension `XAlternativeLayoutRuleTransitional`.
- - - - -
fe3b059c by Andrew Lelechenko at 2026-07-17T04:58:26-04:00
base: re-export GHC.Environment.getFullArgs from System.Environment
CLC proposal https://github.com/haskell/core-libraries-committee/issues/431
- - - - -
722236dd by sheaf at 2026-07-18T08:48:31-04:00
Coercion optimisation: avoid double-Sym for InstCo
Ticket #27374 pointed out an issue with GHC.Core.Coercion.Opt.optCoercion's
handling of InstCo: it contravened (LC2) in Note [The LiftingContext in optCoercion]
because it applied the ambient 'sym' to a coercion that was then added
to the lifting context substitution.
Fixes #27374
Co-authored-by: Simon Jakobi <simon.jakobi(a)gmail.com>
- - - - -
ff70fc75 by sheaf at 2026-07-18T08:48:31-04:00
Coercion optimisation: avoid exponential behaviour
The change to coercion optimisation of 'InstCo' in the previous commit
introduces exponential behaviour to the coercion optimiser. To avoid
this, this commit provides a way to push in 'Sym' of an already-optimised
coercion: GHC.Core.Coercion.Opt.mkDeepSymCo.
See Note [Pushing Sym without re-optimising] in GHC.Core.Coercion.Opt.
- - - - -
dfef27f0 by Duncan Coutts at 2026-07-18T08:49:12-04:00
Move THREADED_RTS-conditional struct members to end of Capability
Accessing members of the Capability struct from CMM code rely on
accessor macros. (The macros are generated by deriveConstants).
These macros have a single definition. This means that the offsets of
all struct members must *not* vary based on THREADED_RTS vs
!THREADED_RTS. This requires that any struct members that are
conditional on THREADED_RTS must occur after the unconditional struct
members. Hence we move all the ones that are conditional on
THREADED_RTS to the end.
Add a deriveConstants entry for the iomgr member of the Capability
struct, which was the motivation for this change.
Add warning messages to help our future selves. Debugging this took me
a couple hours in gdb!
- - - - -
c254e022 by Duncan Coutts at 2026-07-18T08:49:12-04:00
Make the IOManager API use CapIOManager rather than Capability
This makes the API somewhat more self-contained and more consistent.
Now the IOManager API and each of the backends takes just the I/O
manager structure. Previously we had a bit of a mixture, depending on
whether the function needed access to the Capability or just the
CapIOManager.
We still need access to the cap, so we introduce a back reference to
reach the capability, via iomgr->cap.
Convert all uses in select and poll backends, but not win32 ones.
Convert callers in the scheduler and elsewhere.
Also convert the three CMM primops that call IOManager APIs. They just
need to use Capability_iomgr(MyCapability()).
- - - - -
4f3d8f31 by Duncan Coutts at 2026-07-18T08:49:12-04:00
Split posix/MIO.c out of posix/Signals.c
The MIO I/O manager was secretly living inside the Signals file.
Now it gets its own file, like any other self-respecting I/O manager.
- - - - -
52ce04a9 by Duncan Coutts at 2026-07-18T08:49:12-04:00
Rationalise some scheduler run queue utilities
Move them all to the same place in the file.
Make some static that were used only internally.
Also remove a redundant assignment after calling truncateRunQueue that
is already done within truncateRunQueue.
- - - - -
75bbdebc by Duncan Coutts at 2026-07-18T08:49:12-04:00
Rename initIOManager{AfterFork} to {re}startIOManager
These are more accurate names, since these actions happen after
initialisation and are really about starting (or restarting) background
threads.
- - - - -
724c0517 by Duncan Coutts at 2026-07-18T08:49:12-04:00
Free per-cap I/O managers during shutdown and forkProcess
Historically this was not strictly necessary. The select and win32
legacy I/O managers did not maintain any dynamically allocated
resources. The new poll one does (an auxillary table), and so this
should be freed.
After forkProcess, all threads get deleted. This includes threads
waiting on I/O or timers. So as of this patch, resetting the I/O
manager is just about tidying things up. For example, for the poll
I/O manager this will reset the size of the AIOP table (which
otherwise grows but never shrinks).
In future however the re-initialising will become neeecessary for
functionality, since some I/O managers will need to re-initialise
wakeup fds that are set CLOEXEC.
- - - - -
c007d122 by Duncan Coutts at 2026-07-18T08:49:12-04:00
Add a TODO to the MIO I/O manager
The direction of travel is to make I/O managers per-capability and have
all their state live in the struct CapIOManager. The MIO I/O manager
however still has a number of global variables.
It's not obvious how handle these globals however.
- - - - -
b65ab7b3 by Duncan Coutts at 2026-07-18T08:49:12-04:00
Add a FIXME note in the Poll I/O manager
- - - - -
daf2bd6f by Duncan Coutts at 2026-07-18T08:49:12-04:00
Add missing updateRemembSetPushClosure in poll I/O manager
For the non-moving GC.
- - - - -
e33ca830 by Duncan Coutts at 2026-07-18T08:49:12-04:00
Minor doc improvement to struct StgAsyncIOOp member outcome
Mention the enumeration names, as well as their numeric values. The rest
of the code uses the enum names.
- - - - -
4edd2579 by Duncan Coutts at 2026-07-18T08:49:12-04:00
Minor doc improvements for StgTSOBlockInfo
Clarify that certain union members are used only by certain legacy
I/O managers. Hopefully we will be able to remove these at some point.
- - - - -
536bedbb by Duncan Coutts at 2026-07-18T08:49:12-04:00
Avoid exporting various win32-specific rts symbols
The BeginPrivate.h / EndPrivate.h scheme works perfectly well on
Windows, but all of the rts/win32/*.h files were not using it.
- - - - -
8139b5ac by Duncan Coutts at 2026-07-18T08:49:12-04:00
Remove wakeupIOManager, ioManagerWakeup and setIOManagerWakeupFd
We no longer need wakeupIOManager for the threaded RTS case, so we can
remove it and the bits only needed to support it. This includes the
pipe/eventfd fd shared between the RTS and the in-library I/O manager
used for waking up the I/O manager thread. The pipe/eventfd still
exists, but it no longer has to be communicated to the RTS, since the
RTS no longer needs to use it.
So we remove the RTS API export setIOManagerWakeupFd, and remove uses of
it within the I/O managers in ghc-internal.
- - - - -
74fe7c66 by Duncan Coutts at 2026-07-18T08:49:12-04:00
Add a new interruptIOManager API for the I/O managers
It will be used to interrupt awaitCompletedTimeoutsOrIO. Also update the
return type and docs for awaitCompletedTimeoutsOrIO to have it return
false when it gets interrupted, and have no useful post condition in
that case.
- - - - -
38792843 by Duncan Coutts at 2026-07-18T08:49:13-04:00
Add interruptIOManager support for select I/O manager
Uses the FdWakup mechanism.
- - - - -
2f3b00aa by Duncan Coutts at 2026-07-18T08:49:13-04:00
Add interruptIOManager support for poll I/O manager
Uses the FdWakup mechanism.
A quirk we have to cope with is that we now need to poll one more fd --
the wakeup_fd_r -- but this fd has no corresponding entry in the
aiop_table. This is awkward since we have set up our aiop_poll_table to
be an auxilliary table with matching indicies.
The solution this patch uses (and described in the comments) is to have
two tables: struct pollfd *aiop_poll_table, *full_poll_table;
and to have the aiop_poll_table alias the tail of the full_poll_table.
The head entry in the full_poll_table is the extra fd. So we poll the
full_poll_table, while the aiop_poll_table still has matching indicies
with the aiop_table.
Hurrah for C aliasing rules.
- - - - -
cee50131 by Duncan Coutts at 2026-07-18T08:49:13-04:00
Add interruptIOManager support for win32 legacy I/O manager
And remove unused related helper resetAbandonRequestWait. It is not
called because the event is created in auto-reset mode, so never needs
to be reset manually.
- - - - -
cf453143 by Duncan Coutts at 2026-07-18T08:49:13-04:00
Note lack of interruptIOManager support for WinIO I/O manager
Though there's a plausible design, we can't sanely test it at the moment
due to related WinIO bugs. Filed as issue #27403.
- - - - -
1b74a0ad by Duncan Coutts at 2026-07-18T08:49:13-04:00
Be more explicit about enum IOReadOrWrite values, and type within cmm
Belt and braces.
- - - - -
b388d093 by Brian McKenna at 2026-07-18T17:51:50-04:00
Ignore ticks in the pattern-match term oracle
The term-oracle in the pattern-match checker is keyed by a canonical
form of the scrutinee, computed by `makeDictsCoherent`. That canonical
form was tick-sensitive: two occurrences of an otherwise identical
expression that happened to carry different ticks were treated as
distinct values, breaking long-distance information.
This shows up in practice under `-finfo-table-map`, because the
desugarer wraps every record-selector use site in a `SourceNote`
carrying that site's span. For example:
data Box = Box { unBox :: Maybe Int }
f b = case unBox b of
Nothing -> 0
Just _ -> let Just x = unBox b in x
The two `unBox b` expressionss carry different SourceNote spans, the
pattern-match checker sees them as different, the long-distance
information from the outer `Just _` branch never reaches the
let-pattern, and `Just x = unBox b` is wrongly reported as
non-exhaustive.
We now strip all ticks in `makeDictsCoherent`. This is documented as
Wrinkle (UD1) of Note [Unique dictionaries in the TmOracle CoreMap].
Fixes #27314
- - - - -
c23e1acb by Mrjtjmn at 2026-07-18T17:52:45-04:00
Add explanations for unsolved Typeable constraints
This commit adds explanations for unsolved 'Typeable' constraints.
GHC will now provide additional explanations for an unsolved constraint
of the form 'Typeable ty', explain why GHC did not solve Typeable constraint.
e.g.:
- 'ty' is a polymorphic type (e.g. forall a. a -> a)
- 'ty' is a qualified type (e.g. Eq Int => Int)
- 'ty' is an unboxed sum type
- 'ty' is an unreduced type family application
- 'ty' whose kind is not typeable
Fixes #26532
- - - - -
cbef021e by Artem Pelenitsyn at 2026-07-19T07:49:55-04:00
ghc-internal: Lock.hs: fix typo and indentation
- - - - -
42918646 by Duncan Coutts at 2026-07-19T07:50:36-04:00
Fix failing test GcStaticPointers for non-moving GC
Minor mistake in asserting something before checking for that same
thing.
Specifically, Bdescr asserts HEAP_ALLOCED_GC, but Bdescr was being used
prior to a guard that checks HEAP_ALLOCED_GC. The solution is just to
move the use of Bdescr after the guard.
Thanks to Simon Jakobi for identifying the problem.
- - - - -
f865b15b by Wolfgang Jeltsch at 2026-07-21T17:06:14+03:00
Add support for textual output of bytecode file contents
This resolves #26909.
- - - - -
934 changed files:
- .gitignore
- .gitlab-ci.yml
- .gitlab/ci.sh
- .gitlab/generate-ci/gen_ci.hs
- .gitlab/jobs.yaml
- .gitlab/merge_request_templates/Default.md
- .gitlab/rel_eng/mk-ghcup-metadata/mk_ghcup_metadata.py
- .gitlab/test-metrics.sh
- boot
- + changelog.d/26616
- + changelog.d/AbstractQ
- + changelog.d/T17833
- + changelog.d/T21176
- + changelog.d/T21628
- + changelog.d/T26532
- + changelog.d/T26978
- + changelog.d/T27046
- + changelog.d/T27047
- + changelog.d/T27123.md
- + changelog.d/T27182.md
- + changelog.d/T27225
- + changelog.d/T27308
- + changelog.d/T27314.md
- + changelog.d/T27317
- + changelog.d/T27329
- + changelog.d/T27359
- + changelog.d/T27360
- + changelog.d/T27374
- + changelog.d/T27386
- + changelog.d/T27456
- + changelog.d/add_can_drop_to_occurence_analyser
- changelog.d/config
- + changelog.d/deterministic-usage-order
- + changelog.d/fix-absent-dict-projection
- + changelog.d/fix-blackhole-handling
- + changelog.d/fix-cmm-atomic-load-store
- + changelog.d/fix-compacting-gc-ap-27434
- + changelog.d/fix-exponential-case-desugar-27383
- + changelog.d/fix-layout-stack-fcall
- + changelog.d/fix-make-install-j
- + changelog.d/fix-peekitbl-no-tntc
- + changelog.d/fix-plugin-finder-multi-home-unit.md
- + changelog.d/fix-unreg
- + changelog.d/fix-use-std-ap-thunk
- + changelog.d/generically-mconcat
- changelog.d/hadrian-response-files.md
- + changelog.d/hadrian-stale-package-confs-26661
- + changelog.d/hadrian-system-cxx-std-lib-25303
- + changelog.d/inter-module-far-jumps-aarch64-default
- + changelog.d/interactive-error-hints
- + changelog.d/libdir-setting
- + changelog.d/module-graph-reuse-in-downsweep
- changelog.d/more-efficient-home-unit-imports-finding
- + changelog.d/pp-set-ghc-version
- + changelog.d/reexported-module-errors
- + changelog.d/remove-bignum-check-backend
- + changelog.d/remove-bignum-ffi-backend
- + changelog.d/remove-ddump-json-flag
- changelog.d/semaphore-v2
- + changelog.d/stable-core-dump-order-27296
- + changelog.d/stage2-cross-compilers
- + changelog.d/tag-inference-27005
- + changelog.d/tool-messages-27370
- + changelog.d/unused-type
- + changelog.d/windows-rethrow-overlapped-exception
- compiler/.hlint.yaml
- compiler/GHC/Builtin/Names.hs
- compiler/GHC/Builtin/Types.hs
- compiler/GHC/Builtin/Types/Prim.hs
- compiler/GHC/Builtin/Utils.hs
- compiler/GHC/Builtin/primops.txt.pp
- compiler/GHC/ByteCode/Breakpoints.hs
- compiler/GHC/ByteCode/Serialize.hs
- + compiler/GHC/ByteCode/Show.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Cmm/CLabel.hs
- compiler/GHC/Cmm/LayoutStack.hs
- compiler/GHC/Cmm/Parser.y
- compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
- compiler/GHC/CmmToAsm/AArch64/Instr.hs
- compiler/GHC/CmmToAsm/AArch64/Ppr.hs
- compiler/GHC/CmmToAsm/BlockLayout.hs
- compiler/GHC/CmmToAsm/RV64/CodeGen.hs
- compiler/GHC/CmmToAsm/RV64/Instr.hs
- compiler/GHC/CmmToAsm/RV64/Ppr.hs
- compiler/GHC/CmmToAsm/RV64/Regs.hs
- compiler/GHC/CmmToAsm/Reg/Linear.hs
- compiler/GHC/CmmToAsm/Reg/Linear/FreeRegs.hs
- compiler/GHC/CmmToAsm/Reg/Linear/JoinToTargets.hs
- compiler/GHC/CmmToAsm/Reg/Linear/X86.hs
- compiler/GHC/CmmToAsm/Reg/Linear/X86_64.hs
- compiler/GHC/CmmToAsm/X86/RegInfo.hs
- compiler/GHC/CmmToAsm/X86/Regs.hs
- compiler/GHC/Core/Coercion/Opt.hs
- compiler/GHC/Core/Lint.hs
- compiler/GHC/Core/Make.hs
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Core/Opt/OccurAnal.hs
- compiler/GHC/Core/Opt/Simplify.hs
- compiler/GHC/Core/Opt/Specialise.hs
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/Core/Opt/WorkWrap/Utils.hs
- compiler/GHC/Core/Ppr.hs
- compiler/GHC/Core/SimpleOpt.hs
- compiler/GHC/Core/TyCo/Ppr.hs
- compiler/GHC/Core/TyCo/Rep.hs
- compiler/GHC/Core/TyCon.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Utils.hs
- compiler/GHC/CoreToStg/Prep.hs
- compiler/GHC/Data/BooleanFormula.hs
- compiler/GHC/Data/FastString.hs
- compiler/GHC/Data/IOEnv.hs
- compiler/GHC/Data/List/NonEmpty.hs
- compiler/GHC/Data/StringBuffer.hs
- compiler/GHC/Driver/Backend.hs
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/CodeOutput.hs
- compiler/GHC/Driver/Config.hs
- compiler/GHC/Driver/Config/Interpreter.hs
- compiler/GHC/Driver/Config/StgToCmm.hs
- compiler/GHC/Driver/Downsweep.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Errors.hs
- compiler/GHC/Driver/Errors/Ppr.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Main/Compile.hs
- compiler/GHC/Driver/Main/Hsc.hs
- compiler/GHC/Driver/Main/Interactive.hs
- compiler/GHC/Driver/Main/Passes.hs
- compiler/GHC/Driver/Main/Passes.hs-boot
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Driver/Pipeline.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Driver/Session/Units.hs
- compiler/GHC/Hs.hs
- compiler/GHC/Hs/Binds.hs
- compiler/GHC/Hs/Decls.hs
- compiler/GHC/Hs/Doc.hs
- − compiler/GHC/Hs/Doc.hs-boot
- compiler/GHC/Hs/DocString.hs
- compiler/GHC/Hs/Dump.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/Hs/Extension.hs
- + compiler/GHC/Hs/Extension/Pass.hs
- compiler/GHC/Hs/ImpExp.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/Hs/Lit.hs
- compiler/GHC/Hs/Pat.hs
- compiler/GHC/Hs/Stats.hs
- compiler/GHC/Hs/Type.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/HsToCore.hs
- compiler/GHC/HsToCore/Arrows.hs
- compiler/GHC/HsToCore/Breakpoints.hs
- + compiler/GHC/HsToCore/Breakpoints/Types.hs
- compiler/GHC/HsToCore/Docs.hs
- compiler/GHC/HsToCore/Errors/Types.hs
- compiler/GHC/HsToCore/Expr.hs
- compiler/GHC/HsToCore/Foreign/C.hs
- compiler/GHC/HsToCore/Foreign/JavaScript.hs
- compiler/GHC/HsToCore/Foreign/Wasm.hs
- compiler/GHC/HsToCore/Match.hs
- compiler/GHC/HsToCore/Match.hs-boot
- compiler/GHC/HsToCore/Match/Constructor.hs
- compiler/GHC/HsToCore/Match/Literal.hs
- compiler/GHC/HsToCore/Monad.hs
- compiler/GHC/HsToCore/Pmc.hs
- compiler/GHC/HsToCore/Pmc/Desugar.hs
- compiler/GHC/HsToCore/Pmc/Solver.hs
- compiler/GHC/HsToCore/Pmc/Solver/Types.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/HsToCore/Ticks.hs
- compiler/GHC/HsToCore/Usage.hs
- compiler/GHC/Iface/Binary.hs
- compiler/GHC/Iface/Errors.hs
- compiler/GHC/Iface/Errors/Ppr.hs
- compiler/GHC/Iface/Errors/Types.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Iface/Make.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Iface/Syntax.hs
- compiler/GHC/Iface/Type.hs
- compiler/GHC/Iface/Warnings.hs
- compiler/GHC/Linker/Unit.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Annotation.hs
- compiler/GHC/Parser/Errors/Ppr.hs
- compiler/GHC/Parser/HaddockLex.x
- compiler/GHC/Parser/Lexer.x
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Parser/PostProcess/Haddock.hs
- compiler/GHC/Parser/Types.hs
- compiler/GHC/Platform/Ways.hs
- compiler/GHC/Rename/Bind.hs
- compiler/GHC/Rename/Doc.hs
- compiler/GHC/Rename/Env.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/HsType.hs
- compiler/GHC/Rename/Lit.hs
- compiler/GHC/Rename/Module.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Rename/Pat.hs
- compiler/GHC/Rename/Splice.hs
- compiler/GHC/Rename/Splice.hs-boot
- compiler/GHC/Rename/Unbound.hs
- compiler/GHC/Rename/Utils.hs
- compiler/GHC/Runtime/Debugger/Breakpoints.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/Runtime/Eval/Types.hs
- compiler/GHC/Runtime/Heap/Inspect.hs
- compiler/GHC/Settings.hs
- compiler/GHC/Settings/IO.hs
- compiler/GHC/Stg/EnforceEpt.hs
- compiler/GHC/Stg/EnforceEpt/Rewrite.hs
- compiler/GHC/Stg/EnforceEpt/TagSig.hs
- compiler/GHC/Stg/EnforceEpt/Types.hs
- compiler/GHC/StgToByteCode.hs
- compiler/GHC/StgToCmm/Bind.hs
- compiler/GHC/StgToCmm/Config.hs
- compiler/GHC/StgToCmm/Foreign.hs
- compiler/GHC/StgToCmm/Prim.hs
- compiler/GHC/StgToJS/FFI.hs
- compiler/GHC/SysTools/Cpp.hs
- compiler/GHC/SysTools/Process.hs
- compiler/GHC/SysTools/Tasks.hs
- compiler/GHC/SysTools/Terminal.hs
- compiler/GHC/Tc/Deriv.hs
- compiler/GHC/Tc/Deriv/Generate.hs
- compiler/GHC/Tc/Deriv/Generics.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Hole.hs
- compiler/GHC/Tc/Errors/Hole/FitTypes.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Arrow.hs
- compiler/GHC/Tc/Gen/Bind.hs
- compiler/GHC/Tc/Gen/Do.hs
- compiler/GHC/Tc/Gen/Export.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Gen/HsType.hs
- compiler/GHC/Tc/Gen/Match.hs
- compiler/GHC/Tc/Gen/Pat.hs
- compiler/GHC/Tc/Gen/Sig.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Gen/Splice.hs-boot
- compiler/GHC/Tc/Instance/Class.hs
- compiler/GHC/Tc/Instance/Typeable.hs
- compiler/GHC/Tc/Module.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Solver/FunDeps.hs
- compiler/GHC/Tc/TyCl.hs
- compiler/GHC/Tc/TyCl/PatSyn.hs
- compiler/GHC/Tc/TyCl/Utils.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Types/Rank.hs
- compiler/GHC/Tc/Utils/Backpack.hs
- compiler/GHC/Tc/Utils/Env.hs
- compiler/GHC/Tc/Utils/Instantiate.hs
- compiler/GHC/Tc/Utils/Monad.hs
- compiler/GHC/Tc/Utils/TcMType.hs
- compiler/GHC/Tc/Utils/TcType.hs
- compiler/GHC/Tc/Utils/Unify.hs
- compiler/GHC/Tc/Validity.hs
- compiler/GHC/Tc/Zonk/Type.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Types/Basic.hs
- compiler/GHC/Types/Error.hs
- − compiler/GHC/Types/Error.hs-boot
- compiler/GHC/Types/FieldLabel.hs
- compiler/GHC/Types/ForeignCall.hs
- compiler/GHC/Types/Hint/Ppr.hs
- compiler/GHC/Types/Literal.hs
- compiler/GHC/Types/Name/Reader.hs
- compiler/GHC/Types/PkgQual.hs
- compiler/GHC/Types/RepType.hs
- compiler/GHC/Types/SourceError.hs
- compiler/GHC/Types/SourceText.hs
- compiler/GHC/Unit.hs
- compiler/GHC/Unit/Finder.hs
- compiler/GHC/Unit/Finder/Types.hs
- compiler/GHC/Unit/Info.hs
- compiler/GHC/Unit/Module/Deps.hs
- compiler/GHC/Unit/Module/Env.hs
- compiler/GHC/Unit/Module/ModGuts.hs
- compiler/GHC/Unit/Module/ModIface.hs
- compiler/GHC/Unit/Module/Warnings.hs
- compiler/GHC/Unit/Module/WholeCoreBindings.hs
- compiler/GHC/Unit/State.hs
- compiler/GHC/Unit/Types.hs
- compiler/GHC/Utils/Binary.hs
- compiler/GHC/Utils/Error.hs
- compiler/GHC/Utils/Logger.hs
- compiler/GHC/Utils/Misc.hs
- compiler/GHC/Utils/Outputable.hs
- compiler/Language/Haskell/Syntax.hs
- compiler/Language/Haskell/Syntax/Basic.hs
- compiler/Language/Haskell/Syntax/Binds.hs
- compiler/Language/Haskell/Syntax/Binds/InlinePragma.hs
- compiler/Language/Haskell/Syntax/Decls.hs
- compiler/Language/Haskell/Syntax/Decls/Foreign.hs
- + compiler/Language/Haskell/Syntax/Doc.hs
- compiler/Language/Haskell/Syntax/Expr.hs
- compiler/Language/Haskell/Syntax/Expr.hs-boot
- compiler/Language/Haskell/Syntax/Extension.hs
- compiler/Language/Haskell/Syntax/ImpExp.hs
- compiler/Language/Haskell/Syntax/Lit.hs
- compiler/Language/Haskell/Syntax/Module/Name.hs
- compiler/Language/Haskell/Syntax/Pat.hs
- + compiler/Language/Haskell/Syntax/Text.hs
- compiler/Language/Haskell/Syntax/Type.hs
- − compiler/Language/Haskell/Syntax/Type.hs-boot
- compiler/ghc.cabal.in
- configure.ac
- distrib/configure.ac.in
- docs/users_guide/bugs.rst
- docs/users_guide/debugging.rst
- docs/users_guide/expected-undocumented-flags.txt
- docs/users_guide/exts/rank_polymorphism.rst
- docs/users_guide/exts/static_pointers.rst
- docs/users_guide/ghci.rst
- docs/users_guide/javascript.rst
- docs/users_guide/phases.rst
- docs/users_guide/using-optimisation.rst
- docs/users_guide/using.rst
- ghc/GHC/Driver/Session/Mode.hs
- ghc/GHCi/UI.hs
- ghc/GHCi/UI/Exception.hs
- ghc/Main.hs
- hadrian/README.md
- hadrian/bindist/Makefile
- hadrian/bindist/config.mk.in
- hadrian/build-cabal
- hadrian/cabal.project
- hadrian/cfg/default.host.target.in
- + hadrian/cfg/system.config.host.in
- hadrian/cfg/system.config.in
- + hadrian/cfg/system.config.target.in
- hadrian/doc/user-settings.md
- hadrian/hadrian.cabal
- hadrian/src/Base.hs
- + hadrian/src/BindistConfig.hs
- hadrian/src/Builder.hs
- hadrian/src/CommandLine.hs
- hadrian/src/Context.hs
- hadrian/src/Expression.hs
- hadrian/src/Flavour.hs
- hadrian/src/Flavour/Type.hs
- hadrian/src/Hadrian/Builder.hs
- hadrian/src/Hadrian/Builder/Ar.hs
- hadrian/src/Hadrian/Haskell/Cabal/Parse.hs
- hadrian/src/Hadrian/Haskell/Cabal/Type.hs
- hadrian/src/Hadrian/Haskell/Hash.hs
- hadrian/src/Hadrian/Oracles/Path.hs
- hadrian/src/Hadrian/Oracles/TextFile.hs
- hadrian/src/Hadrian/Utilities.hs
- hadrian/src/Main.hs
- hadrian/src/Oracles/Flag.hs
- hadrian/src/Oracles/Flavour.hs
- hadrian/src/Oracles/Setting.hs
- hadrian/src/Oracles/TestSettings.hs
- hadrian/src/Packages.hs
- hadrian/src/Rules.hs
- hadrian/src/Rules/BinaryDist.hs
- hadrian/src/Rules/CabalReinstall.hs
- hadrian/src/Rules/Changelog.hs
- hadrian/src/Rules/Compile.hs
- hadrian/src/Rules/Documentation.hs
- hadrian/src/Rules/Generate.hs
- hadrian/src/Rules/Gmp.hs
- hadrian/src/Rules/Library.hs
- hadrian/src/Rules/Program.hs
- hadrian/src/Rules/Register.hs
- hadrian/src/Rules/Rts.hs
- hadrian/src/Rules/Test.hs
- hadrian/src/Settings.hs
- hadrian/src/Settings/Builders/Cabal.hs
- hadrian/src/Settings/Builders/Common.hs
- hadrian/src/Settings/Builders/Configure.hs
- hadrian/src/Settings/Builders/DeriveConstants.hs
- hadrian/src/Settings/Builders/Ghc.hs
- hadrian/src/Settings/Builders/Hsc2Hs.hs
- hadrian/src/Settings/Builders/RunTest.hs
- hadrian/src/Settings/Builders/SplitSections.hs
- hadrian/src/Settings/Default.hs
- hadrian/src/Settings/Flavours/GhcInGhci.hs
- hadrian/src/Settings/Flavours/Performance.hs
- hadrian/src/Settings/Flavours/QuickCross.hs
- hadrian/src/Settings/Packages.hs
- hadrian/src/Settings/Program.hs
- hadrian/src/Settings/Warnings.hs
- libraries/base/base.cabal.in
- libraries/base/changelog.md
- libraries/base/src/Control/Applicative.hs
- libraries/base/src/Control/Arrow.hs
- libraries/base/src/Control/Monad.hs
- libraries/base/src/Data/Array/Byte.hs
- + libraries/base/src/Data/Double.hs
- libraries/base/src/Data/Fixed.hs
- + libraries/base/src/Data/Float.hs
- libraries/base/src/Data/List/NonEmpty.hs
- libraries/base/src/GHC/Base.hs
- libraries/base/src/GHC/Conc.hs
- libraries/base/src/GHC/Conc/Sync.hs
- libraries/base/src/GHC/Exts.hs
- libraries/base/src/GHC/Fingerprint.hs
- libraries/base/src/GHC/IO/Handle.hs
- libraries/base/src/GHC/RTS/Flags.hs
- libraries/base/src/GHC/Unicode.hs
- libraries/base/src/GHC/Weak.hs
- libraries/base/src/GHC/Weak/Finalize.hs
- libraries/base/src/Prelude.hs
- libraries/base/src/System/Environment.hs
- libraries/base/src/System/IO.hs
- libraries/base/src/System/Mem/Weak.hs
- libraries/base/tests/T15349.stderr
- libraries/base/tests/all.T
- libraries/ghc-bignum/changelog.md
- libraries/ghc-bignum/ghc-bignum.cabal
- libraries/ghc-boot/GHC/Data/ShortText.hs
- libraries/ghc-boot/GHC/Settings/Utils.hs
- libraries/ghc-experimental/src/GHC/PrimOps.hs
- + libraries/ghc-heap/tests/T27465.hs
- + libraries/ghc-heap/tests/T27465.stdout
- libraries/ghc-heap/tests/all.T
- libraries/ghc-internal/bignum-backend.rst
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/src/GHC/Internal/Bignum/Backend.hs
- − libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/Check.hs
- − libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/FFI.hs
- libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/Native.hs
- − libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/Selected.hs
- libraries/ghc-internal/src/GHC/Internal/Bignum/Integer.hs
- libraries/ghc-internal/src/GHC/Internal/Bits.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Control.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Manager.hs
- libraries/ghc-internal/src/GHC/Internal/Event/TimerManager.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Windows.hsc
- libraries/ghc-internal/src/GHC/Internal/Exception/Type.hs
- libraries/ghc-internal/src/GHC/Internal/Float.hs
- libraries/ghc-internal/src/GHC/Internal/Generics.hs
- libraries/ghc-internal/src/GHC/Internal/Heap/InfoTable.hsc
- libraries/ghc-internal/src/GHC/Internal/Heap/InfoTableProf.hsc
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Lock.hs
- libraries/ghc-internal/src/GHC/Internal/Lexeme.hs
- libraries/ghc-internal/src/GHC/Internal/Natural.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lib.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Monad.hs
- libraries/ghc-internal/src/GHC/Internal/Types.hs
- libraries/ghc-internal/tests/backtraces/T14532b.stdout
- libraries/ghci/GHCi/TH.hs
- libraries/process
- libraries/semaphore-compat
- libraries/template-haskell/Language/Haskell/TH/Syntax.hs
- libraries/xhtml
- m4/fp_find_nm.m4
- m4/prep_target_file.m4
- nofib
- rts/Apply.cmm
- rts/Capability.c
- rts/Capability.h
- rts/ContinuationOps.cmm
- rts/IOManager.c
- rts/IOManager.h
- rts/IOManagerInternals.h
- rts/Messages.c
- rts/PrimOps.cmm
- rts/RaiseAsync.c
- rts/RtsStartup.c
- rts/RtsSymbols.c
- rts/Schedule.c
- rts/Schedule.h
- rts/ThreadPaused.c
- rts/Threads.c
- rts/Ticker.h
- rts/Timer.c
- rts/Timer.h
- rts/Updates.h
- rts/eventlog/EventLog.c
- rts/eventlog/EventLog.h
- rts/include/rts/IOInterface.h
- rts/include/rts/NonMoving.h
- rts/include/rts/OSThreads.h
- rts/include/rts/Timer.h
- rts/include/rts/storage/ClosureMacros.h
- rts/include/rts/storage/Closures.h
- rts/include/rts/storage/TSO.h
- rts/include/stg/MiscClosures.h
- rts/posix/FdWakeup.h
- + rts/posix/MIO.c
- + rts/posix/MIO.h
- rts/posix/Poll.c
- rts/posix/Poll.h
- rts/posix/Select.c
- rts/posix/Select.h
- rts/posix/Signals.c
- rts/posix/Signals.h
- rts/posix/Ticker.c
- rts/posix/Timeout.c
- rts/posix/Timeout.h
- rts/rts.cabal
- rts/sm/BlockAlloc.c
- rts/sm/Compact.c
- rts/sm/Evac.h
- rts/sm/GC.c
- rts/sm/MBlock.c
- rts/sm/NonMovingMark.c
- rts/win32/AsyncMIO.c
- rts/win32/AsyncMIO.h
- rts/win32/AsyncWinIO.h
- rts/win32/AwaitEvent.c
- rts/win32/AwaitEvent.h
- rts/win32/ConsoleHandler.h
- rts/win32/MIOManager.h
- rts/win32/ThrIOManager.h
- rts/win32/Ticker.c
- rts/win32/WorkQueue.h
- rts/win32/libHSghc-internal.def.in
- rts/win32/veh_excn.h
- testsuite/driver/junit.py
- testsuite/driver/perf_notes.py
- testsuite/driver/runtests.py
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
- testsuite/driver/testutil.py
- testsuite/ghc-config/ghc-config.hs
- testsuite/mk/test.mk
- testsuite/tests/MiniQuickCheck.hs
- testsuite/tests/annotations/should_fail/annfail03.stderr
- testsuite/tests/annotations/should_fail/annfail04.stderr
- testsuite/tests/annotations/should_fail/annfail06.stderr
- testsuite/tests/annotations/should_fail/annfail09.stderr
- testsuite/tests/arityanal/should_compile/T21755.stderr
- testsuite/tests/arityanal/should_compile/all.T
- testsuite/tests/backpack/should_compile/T13149.bkp
- testsuite/tests/bytecode/TLinkable/all.T
- testsuite/tests/cmm/should_compile/all.T
- testsuite/tests/cmm/should_run/AtomicFetch.hs
- testsuite/tests/cmm/should_run/AtomicFetch_cmm.cmm
- + testsuite/tests/cmm/should_run/T27447.hs
- + testsuite/tests/cmm/should_run/T27447.stdout
- + testsuite/tests/cmm/should_run/T27447_cmm.cmm
- testsuite/tests/cmm/should_run/all.T
- testsuite/tests/codeGen/should_compile/T25177.stderr
- + testsuite/tests/codeGen/should_gen_asm/aarch64-sxth-mul2.asm
- + testsuite/tests/codeGen/should_gen_asm/aarch64-sxth-mul2.cmm
- + testsuite/tests/codeGen/should_gen_asm/aarch64-sxtw.asm
- + testsuite/tests/codeGen/should_gen_asm/aarch64-sxtw.cmm
- testsuite/tests/codeGen/should_gen_asm/all.T
- testsuite/tests/codeGen/should_run/T16617.hs
- testsuite/tests/codeGen/should_run/T16617.stdout
- + testsuite/tests/codeGen/should_run/T27046.hs
- + testsuite/tests/codeGen/should_run/T27046_cmm.cmm
- + testsuite/tests/codeGen/should_run/aarch64-sxtw-cmm.cmm
- + testsuite/tests/codeGen/should_run/aarch64-sxtw-run.hs
- + testsuite/tests/codeGen/should_run/aarch64-sxtw-run.stdout
- testsuite/tests/codeGen/should_run/all.T
- testsuite/tests/codeGen/should_run/cgrun025.stderr
- + testsuite/tests/concurrent/should_run/T27105.hs
- testsuite/tests/concurrent/should_run/all.T
- testsuite/tests/core-to-stg/T14895.stderr
- testsuite/tests/core-to-stg/T25284/Cls.hs
- + testsuite/tests/core-to-stg/T25924/B.hs
- + testsuite/tests/core-to-stg/T25924/Main.hs
- + testsuite/tests/core-to-stg/T25924/all.T
- + testsuite/tests/core-to-stg/T25924a.hs
- + testsuite/tests/core-to-stg/T25924a.stdout
- testsuite/tests/core-to-stg/all.T
- + testsuite/tests/corelint/T27374.hs
- testsuite/tests/corelint/all.T
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- + testsuite/tests/deSugar/should_compile/T27383.hs
- testsuite/tests/deSugar/should_compile/all.T
- testsuite/tests/deSugar/should_fail/all.T
- testsuite/tests/deSugar/should_run/all.T
- testsuite/tests/deriving/should_compile/all.T
- testsuite/tests/determinism/determ017/A.hs
- testsuite/tests/dmdanal/should_compile/T18982.stderr
- testsuite/tests/driver/T16167.stderr
- − testsuite/tests/driver/T16167.stdout
- + testsuite/tests/driver/T27370/Makefile
- + testsuite/tests/driver/T27370/T27370.hs
- + testsuite/tests/driver/T27370/T27370.pp
- + testsuite/tests/driver/T27370/T27370.stderr
- + testsuite/tests/driver/T27370/all.T
- testsuite/tests/driver/all.T
- testsuite/tests/driver/json2.stderr
- − testsuite/tests/driver/json_dump.hs
- − testsuite/tests/driver/json_dump.stderr
- + testsuite/tests/driver/multipleHomeUnits/plugin01/all.T
- + testsuite/tests/driver/multipleHomeUnits/plugin01/appunit
- + testsuite/tests/driver/multipleHomeUnits/plugin01/p/MyPlugin.hs
- + testsuite/tests/driver/multipleHomeUnits/plugin01/pluginunit
- + testsuite/tests/driver/multipleHomeUnits/plugin01/q/App.hs
- + testsuite/tests/driver/multipleHomeUnits/plugin02/all.T
- + testsuite/tests/driver/multipleHomeUnits/plugin02/appunit
- + testsuite/tests/driver/multipleHomeUnits/plugin02/p/MyPlugin.hs
- + testsuite/tests/driver/multipleHomeUnits/plugin02/pluginunit
- + testsuite/tests/driver/multipleHomeUnits/plugin02/q/App.hs
- + testsuite/tests/driver/multipleHomeUnits/plugin02/r/RexLib.hs
- + testsuite/tests/driver/multipleHomeUnits/plugin02/reexportunit
- testsuite/tests/driver/options_ghc/Mod_fbyte_code.hs
- testsuite/tests/driver/options_ghc/all.T
- testsuite/tests/driver/options_ghc/options_ghc_fbyte-code.stderr
- testsuite/tests/exceptions/T26759.stderr
- testsuite/tests/generics/GenDerivOutput.hs
- testsuite/tests/generics/GenDerivOutput1_0.hs
- testsuite/tests/generics/GenDerivOutput1_1.hs
- testsuite/tests/generics/T10604/T10604_deriving.hs
- testsuite/tests/generics/T10604/all.T
- + testsuite/tests/generics/T27245.hs
- + testsuite/tests/generics/T27245.stdout
- testsuite/tests/generics/all.T
- testsuite/tests/ghc-api/T25121_status.stdout
- + testsuite/tests/ghc-api/T27240.hs
- testsuite/tests/ghc-api/all.T
- testsuite/tests/ghc-api/annotations-literals/literals.stdout
- testsuite/tests/ghc-api/annotations-literals/parsed.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/A.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/B.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/C.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/D.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/X.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/Y.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.modules/Z.hs
- + testsuite/tests/ghc-api/downsweep/IncrementalDownsweep.stdout
- testsuite/tests/ghc-api/downsweep/OldModLocation.hs
- testsuite/tests/ghc-api/downsweep/PartialDownsweep.hs
- testsuite/tests/ghc-api/downsweep/all.T
- testsuite/tests/ghc-api/exactprint/T22919.stderr
- testsuite/tests/ghc-api/exactprint/Test20239.stderr
- testsuite/tests/ghc-api/exactprint/ZeroWidthSemi.stderr
- testsuite/tests/ghc-api/fixed-nodes/InterfaceModuleGraph.hs
- + testsuite/tests/ghc-api/settings/LibDir.hs
- + testsuite/tests/ghc-api/settings/LibDir.stdout
- + testsuite/tests/ghc-api/settings/all.T
- testsuite/tests/ghc-e/should_fail/T18441fail7.stderr
- testsuite/tests/ghc-e/should_fail/all.T
- testsuite/tests/ghci.debugger/scripts/all.T
- testsuite/tests/ghci/prog-mhu002/prog-mhu002c.stdout
- testsuite/tests/ghci/scripts/T12005.script
- testsuite/tests/ghci/scripts/all.T
- + testsuite/tests/ghci/scripts/bytecodeIPE.hs
- + testsuite/tests/ghci/scripts/bytecodeIPE.script
- + testsuite/tests/ghci/scripts/bytecodeIPE.stdout
- testsuite/tests/ghci/scripts/ghci024.stdout
- testsuite/tests/ghci/scripts/ghci024.stdout-mingw32
- testsuite/tests/ghci/should_run/Makefile
- + testsuite/tests/ghci/should_run/T27287.hs
- + testsuite/tests/ghci/should_run/T27287.stdout
- testsuite/tests/ghci/should_run/all.T
- testsuite/tests/haddock/haddock_testsuite/Makefile
- testsuite/tests/haddock/haddock_testsuite/all.T
- testsuite/tests/haddock/perf/Fold.hs
- testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr
- testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr
- testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr
- testsuite/tests/indexed-types/should_fail/T7354.hs
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/interface-stability/ghc-bignum-exports.stdout
- testsuite/tests/interface-stability/ghc-prim-exports.stdout
- testsuite/tests/interface-stability/ghc-prim-exports.stdout-mingw32
- testsuite/tests/interface-stability/template-haskell-exports.stdout
- testsuite/tests/javascript/closure/all.T
- testsuite/tests/layout/layout001.stdout
- testsuite/tests/layout/layout002.stdout
- testsuite/tests/layout/layout003.stdout
- testsuite/tests/layout/layout004.stdout
- testsuite/tests/layout/layout005.stdout
- testsuite/tests/layout/layout006.stdout
- testsuite/tests/layout/layout007.stdout
- testsuite/tests/layout/layout008.stdout
- testsuite/tests/layout/layout009.stdout
- testsuite/tests/linear/should_compile/T1735Min.hs
- testsuite/tests/mdo/should_fail/mdofail006.stderr
- testsuite/tests/module/mod185.stderr
- testsuite/tests/numeric/should_compile/T15547.stderr
- + testsuite/tests/numeric/should_run/T21176.hs
- + testsuite/tests/numeric/should_run/T21176.stdout
- + testsuite/tests/numeric/should_run/T21176.stdout-ws-32
- testsuite/tests/numeric/should_run/all.T
- testsuite/tests/numeric/should_run/foundation.hs
- testsuite/tests/overloadedrecflds/should_compile/DRFPatSynExport.stdout
- + testsuite/tests/package/ImportReexport.hs
- + testsuite/tests/package/ImportReexport.stderr
- testsuite/tests/package/all.T
- testsuite/tests/parser/should_compile/DumpParsedAst.stderr
- testsuite/tests/parser/should_compile/DumpParsedAstComments.stderr
- testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
- testsuite/tests/parser/should_compile/DumpSemis.stderr
- testsuite/tests/parser/should_compile/DumpTypecheckedAst.stderr
- testsuite/tests/parser/should_compile/KindSigs.stderr
- + testsuite/tests/parser/should_compile/T13087.stderr
- testsuite/tests/parser/should_compile/T14189.stderr
- testsuite/tests/parser/should_compile/T15279.stderr
- testsuite/tests/parser/should_compile/T15323.stderr
- testsuite/tests/parser/should_compile/T20452.stderr
- testsuite/tests/parser/should_compile/T20718.stderr
- testsuite/tests/parser/should_compile/T20718b.stderr
- testsuite/tests/parser/should_compile/T20846.stderr
- testsuite/tests/parser/should_compile/T23315/T23315.stderr
- testsuite/tests/parser/should_compile/all.T
- testsuite/tests/parser/should_fail/T8431.stderr
- testsuite/tests/parser/should_fail/readFail038.stderr
- + testsuite/tests/parser/should_run/StringStartsWithNull.hs
- + testsuite/tests/parser/should_run/StringStartsWithNull.stdout
- testsuite/tests/parser/should_run/all.T
- testsuite/tests/perf/compiler/T11068.stdout
- + testsuite/tests/perf/compiler/T26426.hs
- testsuite/tests/perf/compiler/T3064.hs
- testsuite/tests/perf/compiler/all.T
- testsuite/tests/perf/compiler/hard_hole_fits.stderr
- + testsuite/tests/perf/should_run/T11226.hs
- + testsuite/tests/perf/should_run/T11226.stdout
- testsuite/tests/perf/should_run/all.T
- testsuite/tests/pmcheck/should_compile/T12957.stderr
- + testsuite/tests/pmcheck/should_compile/T27314.hs
- + testsuite/tests/pmcheck/should_compile/T27360.hs
- testsuite/tests/pmcheck/should_compile/all.T
- testsuite/tests/polykinds/T7594.hs
- testsuite/tests/printer/AnnotationNoListTuplePuns.stdout
- testsuite/tests/printer/T18052a.stderr
- testsuite/tests/printer/T18791.stderr
- testsuite/tests/printer/Test10309.hs
- testsuite/tests/printer/Test20297.stdout
- testsuite/tests/printer/Test24533.stdout
- testsuite/tests/printer/all.T
- testsuite/tests/profiling/perf/T23103/all.T
- + testsuite/tests/profiling/should_compile/T27182.hs
- + testsuite/tests/profiling/should_compile/T27386.hs
- testsuite/tests/profiling/should_compile/all.T
- + testsuite/tests/profiling/should_run/T27225.hs
- + testsuite/tests/profiling/should_run/T27225.stdout
- + testsuite/tests/profiling/should_run/T27225b.hs
- + testsuite/tests/profiling/should_run/T27225b.stdout
- testsuite/tests/profiling/should_run/all.T
- testsuite/tests/profiling/should_run/caller-cc/CallerCc1.prof.sample
- testsuite/tests/profiling/should_run/callstack001.stdout
- testsuite/tests/profiling/should_run/scc001.prof.sample
- testsuite/tests/profiling/should_run/staticcallstack002.stdout
- testsuite/tests/programs/thurston-modular-arith/Main.hs
- testsuite/tests/quasiquotation/qq001/qq001.stderr
- testsuite/tests/quasiquotation/qq002/qq002.stderr
- testsuite/tests/quasiquotation/qq003/qq003.stderr
- testsuite/tests/quasiquotation/qq004/qq004.stderr
- testsuite/tests/quotes/LiftErrMsg.stderr
- testsuite/tests/quotes/LiftErrMsgDefer.stderr
- testsuite/tests/quotes/LiftErrMsgTyped.stderr
- testsuite/tests/quotes/T10384.stderr
- testsuite/tests/quotes/T5721.stderr
- testsuite/tests/quotes/TH_localname.stderr
- testsuite/tests/rename/should_compile/T1792_imports.stdout
- testsuite/tests/rename/should_compile/T18264.stdout
- testsuite/tests/rename/should_compile/T4239.stdout
- testsuite/tests/rts/T17574.hs
- testsuite/tests/rts/T19381.hs
- + testsuite/tests/rts/T27123.hs
- testsuite/tests/rts/T27131.hs
- testsuite/tests/rts/T27131.stdout
- + testsuite/tests/rts/T27434.hs
- + testsuite/tests/rts/T27434.stdout
- testsuite/tests/rts/all.T
- testsuite/tests/rts/ipe/IpeStats/Fold.hs
- testsuite/tests/rts/ipe/T24005/all.T
- testsuite/tests/runghc/T7859.stderr-mingw32
- + testsuite/tests/show-bytecode/Example.hs
- + testsuite/tests/show-bytecode/Makefile
- + testsuite/tests/show-bytecode/all.T
- + testsuite/tests/show-bytecode/show-bytecode-breakpoints.stdout
- + testsuite/tests/show-bytecode/show-bytecode-hpc.stdout
- + testsuite/tests/show-bytecode/show-bytecode-vanilla.stdout
- testsuite/tests/showIface/DocsInHiFile1.stdout
- testsuite/tests/showIface/DocsInHiFileTH.stdout
- testsuite/tests/showIface/HaddockSpanIssueT24378.stdout
- testsuite/tests/showIface/MagicHashInHaddocks.stdout
- testsuite/tests/showIface/NoExportList.stdout
- testsuite/tests/simplCore/should_compile/DataToTagFamilyScrut.stderr
- testsuite/tests/simplCore/should_compile/Makefile
- testsuite/tests/simplCore/should_compile/T11562.hs
- testsuite/tests/simplCore/should_compile/T13156.stdout
- testsuite/tests/simplCore/should_compile/T14978.stdout
- testsuite/tests/simplCore/should_compile/T18013.stderr
- testsuite/tests/simplCore/should_compile/T24229a.stderr
- testsuite/tests/simplCore/should_compile/T24229b.stderr
- testsuite/tests/simplCore/should_compile/T26615.stderr
- + testsuite/tests/simplCore/should_compile/T27296.hs
- + testsuite/tests/simplCore/should_compile/T27296.stdout
- + testsuite/tests/simplCore/should_compile/T27296b.hs
- + testsuite/tests/simplCore/should_compile/T27296b.stdout
- + testsuite/tests/simplCore/should_compile/T4081.hs
- + testsuite/tests/simplCore/should_compile/T4081.stderr
- testsuite/tests/simplCore/should_compile/T4201.stdout
- testsuite/tests/simplCore/should_compile/T8832.hs
- testsuite/tests/simplCore/should_compile/T8832.stdout
- testsuite/tests/simplCore/should_compile/all.T
- + testsuite/tests/simplCore/should_run/T27005.hs
- + testsuite/tests/simplCore/should_run/T27005.stdout
- + testsuite/tests/simplCore/should_run/T27005_aux.hs
- testsuite/tests/simplCore/should_run/T3591.hs
- testsuite/tests/simplCore/should_run/all.T
- testsuite/tests/simplStg/should_compile/T24806.hs
- testsuite/tests/simplStg/should_compile/T24806.stderr
- + testsuite/tests/simplStg/should_compile/T27005b.hs
- + testsuite/tests/simplStg/should_compile/T27005b.stderr
- testsuite/tests/simplStg/should_compile/all.T
- testsuite/tests/simplStg/should_compile/inferTags004.hs
- testsuite/tests/simplStg/should_compile/inferTags004.stderr
- + testsuite/tests/simplStg/should_run/T27005a.hs
- + testsuite/tests/simplStg/should_run/T27005a.stdout
- testsuite/tests/simplStg/should_run/all.T
- testsuite/tests/splice-imports/SI03.stderr
- testsuite/tests/splice-imports/SI05.stderr
- testsuite/tests/splice-imports/SI08.stderr
- testsuite/tests/splice-imports/SI08_oneshot.stderr
- testsuite/tests/splice-imports/SI16.stderr
- testsuite/tests/splice-imports/SI18.stderr
- testsuite/tests/splice-imports/SI20.stderr
- testsuite/tests/splice-imports/SI25.stderr
- testsuite/tests/splice-imports/SI28.stderr
- testsuite/tests/splice-imports/SI29.stderr
- testsuite/tests/splice-imports/SI31.stderr
- testsuite/tests/splice-imports/SI36.stderr
- testsuite/tests/splice-imports/T26088.stderr
- testsuite/tests/splice-imports/T26090.stderr
- + testsuite/tests/splice-imports/T26616.hs
- + testsuite/tests/splice-imports/T26616.stderr
- testsuite/tests/splice-imports/all.T
- testsuite/tests/th/T16976z.stderr
- testsuite/tests/th/T17820a.stderr
- testsuite/tests/th/T17820b.stderr
- testsuite/tests/th/T17820c.stderr
- testsuite/tests/th/T17820d.stderr
- testsuite/tests/th/T17820e.stderr
- testsuite/tests/th/T21547.stderr
- testsuite/tests/th/T23829_hasty.stderr
- testsuite/tests/th/T23829_hasty_b.stderr
- testsuite/tests/th/T23829_tardy.ghc.stderr
- testsuite/tests/th/T26098_local.stderr
- testsuite/tests/th/T26098_quote.stderr
- testsuite/tests/th/T26098_splice.stderr
- testsuite/tests/th/T26099.stderr
- testsuite/tests/th/T26568.stderr
- testsuite/tests/th/T5795.stderr
- testsuite/tests/typecheck/should_compile/DeepSubsumption02.hs
- testsuite/tests/typecheck/should_compile/T12507.hs
- testsuite/tests/typecheck/should_compile/T13951.hs
- testsuite/tests/typecheck/should_compile/T15242.stderr
- testsuite/tests/typecheck/should_compile/T18920.hs
- testsuite/tests/typecheck/should_compile/T2595.hs
- testsuite/tests/typecheck/should_compile/T7541.hs
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_compile/subsumption_sort_hole_fits.stderr
- testsuite/tests/typecheck/should_fail/T13292.stderr
- testsuite/tests/typecheck/should_fail/T15067.stderr
- + testsuite/tests/typecheck/should_fail/T26532.hs
- + testsuite/tests/typecheck/should_fail/T26532.stderr
- + testsuite/tests/typecheck/should_fail/T27390-explicit-kinds.stderr
- + testsuite/tests/typecheck/should_fail/T27390.hs
- + testsuite/tests/typecheck/should_fail/T27390.stderr
- + testsuite/tests/typecheck/should_fail/T27390a.hs
- testsuite/tests/typecheck/should_fail/T6069.stderr
- testsuite/tests/typecheck/should_fail/T7368a.hs
- testsuite/tests/typecheck/should_fail/T9858b.stderr
- testsuite/tests/typecheck/should_fail/TcStaticPointersFail02.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/typecheck/should_run/T1735_Help/Basics.hs
- testsuite/tests/typecheck/should_run/T3731-short.hs
- testsuite/tests/typecheck/should_run/T3731.hs
- testsuite/tests/typecheck/should_run/church.hs
- testsuite/tests/typecheck/should_run/tcrun008.hs
- testsuite/tests/typecheck/should_run/tcrun017.hs
- testsuite/tests/typecheck/should_run/tcrun026.hs
- testsuite/tests/typecheck/should_run/tcrun035.hs
- testsuite/tests/typecheck/should_run/tcrun036.hs
- utils/check-exact/ExactPrint.hs
- utils/check-exact/Main.hs
- utils/check-exact/Preprocess.hs
- utils/check-exact/Transform.hs
- utils/check-exact/Utils.hs
- utils/check-exact/check-exact.cabal
- utils/deriveConstants/Main.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Program.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Utils.hs
- utils/haddock/CONTRIBUTING.md
- utils/haddock/haddock-api/haddock-api.cabal
- utils/haddock/haddock-api/src/Haddock.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hoogle.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Hyperlinker/Parser.hs
- utils/haddock/haddock-api/src/Haddock/Backends/LaTeX.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Decl.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/DocMarkup.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Meta.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Names.hs
- utils/haddock/haddock-api/src/Haddock/Backends/Xhtml/Utils.hs
- utils/haddock/haddock-api/src/Haddock/Convert.hs
- utils/haddock/haddock-api/src/Haddock/Doc.hs
- utils/haddock/haddock-api/src/Haddock/GhcUtils.hs
- utils/haddock/haddock-api/src/Haddock/Interface/AttachInstances.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Create.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Json.hs
- utils/haddock/haddock-api/src/Haddock/Interface/LexParseRn.hs
- utils/haddock/haddock-api/src/Haddock/Interface/ParseModuleHeader.hs
- utils/haddock/haddock-api/src/Haddock/Interface/Rename.hs
- utils/haddock/haddock-api/src/Haddock/Interface/RenameType.hs
- utils/haddock/haddock-api/src/Haddock/InterfaceFile.hs
- utils/haddock/haddock-api/src/Haddock/Options.hs
- utils/haddock/haddock-api/src/Haddock/Parser.hs
- utils/haddock/haddock-api/src/Haddock/Types.hs
- utils/haddock/haddock-api/src/Haddock/Utils.hs
- utils/haddock/haddock-api/src/Haddock/Utils/Json.hs
- utils/haddock/haddock-api/src/Haddock/Utils/Json/Parser.hs
- utils/haddock/haddock-api/src/Haddock/Utils/Json/Types.hs
- utils/haddock/haddock-library/src/Documentation/Haddock/Doc.hs
- utils/haddock/haddock-library/src/Documentation/Haddock/Markup.hs
- utils/haddock/haddock-library/src/Documentation/Haddock/Parser.hs
- utils/haddock/haddock-library/src/Documentation/Haddock/Parser/Util.hs
- utils/haddock/haddock-library/src/Documentation/Haddock/Types.hs
- utils/haddock/haddock-library/test/Documentation/Haddock/ParserSpec.hs
- utils/haddock/haddock-test/haddock-test.cabal
- utils/haddock/haddock-test/src/Test/Haddock/Config.hs
- utils/haddock/html-test/ref/Hash.html
- utils/haddock/html-test/ref/Test.html
- utils/haddock/html-test/ref/TypeFamilies3.html
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/12d74b588fdee0f0bb129bafc4c6c2…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/12d74b588fdee0f0bb129bafc4c6c2…
You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
1
0
[Git][ghc/ghc][wip/fendor/external-unit-db-cache] 9 commits: Fixup: Expose TrustOverlay API and add docs
by Hannes Siebenhandl (@fendor) 21 Jul '26
by Hannes Siebenhandl (@fendor) 21 Jul '26
21 Jul '26
Hannes Siebenhandl pushed to branch wip/fendor/external-unit-db-cache at Glasgow Haskell Compiler / GHC
Commits:
5aa49c01 by fendor at 2026-07-21T13:59:21+02:00
Fixup: Expose TrustOverlay API and add docs
- - - - -
2bc401c5 by fendor at 2026-07-21T14:07:26+02:00
Fixup: get rid of commented out fields
- - - - -
34290c1b by fendor at 2026-07-21T14:08:34+02:00
Fixup: get rid of unproven bang for homeUnitDepends
- - - - -
07901d15 by fendor at 2026-07-21T14:14:18+02:00
Fixup: remove debug remnant
- - - - -
0b32af7b by fendor at 2026-07-21T14:21:15+02:00
Fixup: Strictness of TrustOverlay field
- - - - -
2f7b984e by fendor at 2026-07-21T14:38:08+02:00
fixup! Add test for multiple home units to show that the number of UnitInfo's doesn't increase
- - - - -
3120f9cf by fendor at 2026-07-21T15:42:29+02:00
Fixup: better docs and notes for UnitIndex vs UnitState
- - - - -
7bc96202 by fendor at 2026-07-21T16:04:14+02:00
Fixup: Move ExternalDatatbaseCache into UnitIndex
- - - - -
02a77b79 by fendor at 2026-07-21T16:04:48+02:00
Fixup: one better comment
- - - - -
11 changed files:
- compiler/GHC.hs
- compiler/GHC/Driver/Backpack.hs
- compiler/GHC/Driver/Env.hs
- compiler/GHC/Driver/Session/Units.hs
- compiler/GHC/Unit/Env.hs
- compiler/GHC/Unit/External/Database.hs
- compiler/GHC/Unit/External/Index.hs
- compiler/GHC/Unit/State.hs
- ghc/GHCi/UI.hs
- + testsuite/tests/driver/TUnitInfo/generic-unit-info-space-mhu.stdout
- testsuite/tests/driver/TUnitInfo/generic-unit-info-space.hs
Changes:
=====================================
compiler/GHC.hs
=====================================
@@ -671,7 +671,7 @@ setUnitDynFlagsNoCheck uid dflags1 = do
logger <- getLogger
hsc_env <- getSession
- (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags1 (hscUIC hsc_env) (hscEUDC hsc_env) (hsc_all_home_unit_ids hsc_env)
+ (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags1 (hscUIC hsc_env) (hsc_all_home_unit_ids hsc_env)
updated_dflags <- liftIO $ updatePlatformConstants dflags1 mconstants
let upd hue =
@@ -760,7 +760,7 @@ setProgramDynFlags_ invalidate_needed dflags = do
old_hpt = homeUnitEnv_hpt homeUnitEnv
home_units = HUG.allUnits (ue_home_unit_graph old_unit_env)
- (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags (ue_uic old_unit_env) (ue_eud old_unit_env) home_units
+ (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags (ue_uic old_unit_env) home_units
updated_dflags <- liftIO $ updatePlatformConstants dflags0 mconstants
pure HomeUnitEnv
@@ -778,7 +778,6 @@ setProgramDynFlags_ invalidate_needed dflags = do
, ue_current_unit = ue_currentUnit old_unit_env
, ue_module_graph = ue_module_graph old_unit_env
, ue_eps = ue_eps old_unit_env
- , ue_eud = ue_eud old_unit_env
, ue_uic = ue_uic old_unit_env
}
modifySession $ \h -> hscSetFlags dflags1 h{ hsc_unit_env = unit_env }
@@ -837,7 +836,6 @@ setProgramHUG_ invalidate_needed new_hug0 = do
, ue_current_unit = ue_currentUnit unit_env0
, ue_eps = ue_eps unit_env0
, ue_module_graph = ue_module_graph unit_env0
- , ue_eud = ue_eud unit_env0
, ue_uic = ue_uic unit_env0
}
modifySession $ \h ->
@@ -886,7 +884,7 @@ setProgramHUG_ invalidate_needed new_hug0 = do
old_hpt = homeUnitEnv_hpt homeUnitEnv
home_units = HUG.allUnits (ue_home_unit_graph unit_env)
- (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags (ue_uic unit_env) (ue_eud unit_env) home_units
+ (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags (ue_uic unit_env) home_units
updated_dflags <- liftIO $ updatePlatformConstants dflags mconstants
pure HomeUnitEnv
=====================================
compiler/GHC/Driver/Backpack.hs
=====================================
@@ -92,7 +92,7 @@ import GHC.Types.Error (mkUnknownDiagnostic)
import qualified GHC.Unit.Home.Graph as HUG
import GHC.Unit.Home.ModInfo
import GHC.Unit.Home.PackageTable
-import GHC.Unit.External.Database (cacheExternalUnitDatabase)
+import GHC.Unit.External.Index (cacheExternalUnitDatabase)
-- | Entry point to compile a Backpack file.
doBackpack :: [FilePath] -> Ghc ()
@@ -442,8 +442,8 @@ addInMemoryDatabase dflags u = do
{ unitDatabasePath = unsafeEncodeUtf $ "(in memory " ++ showSDoc dflags (ppr (unitId u)) ++ ")"
, unitDatabaseUnits = [u]
}
- let eud = hscEUDC hsc_env
- liftIO $ cacheExternalUnitDatabase eud newdb
+ let uic = hscUIC hsc_env
+ liftIO $ cacheExternalUnitDatabase uic newdb
-- added at the end because ordering matters
pure dflags
{ packageDBFlags = packageDBFlags dflags ++ [PackageDB (PkgDbPath (unitDatabasePath newdb))]
@@ -456,11 +456,10 @@ addUnit u = do
logger <- getLogger
let dflags0 = hsc_dflags hsc_env
let old_unit_env = hsc_unit_env hsc_env
- let eud = hscEUDC hsc_env
dflags1 <- addInMemoryDatabase dflags0 u
- (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags1 (ue_uic old_unit_env) eud (hsc_all_home_unit_ids hsc_env)
+ (unit_state,home_unit,mconstants) <- liftIO $ initUnits logger dflags1 (ue_uic old_unit_env) (hsc_all_home_unit_ids hsc_env)
-- update platform constants
@@ -477,7 +476,6 @@ addUnit u = do
(HUG.mkHomeUnitEnv unit_state dflags (ue_hpt old_unit_env) (Just home_unit))
, ue_eps = ue_eps old_unit_env
, ue_module_graph = ue_module_graph old_unit_env
- , ue_eud = ue_eud old_unit_env
, ue_uic = ue_uic old_unit_env
}
setSession $ hscSetFlags dflags $ hsc_env { hsc_unit_env = unit_env }
=====================================
compiler/GHC/Driver/Env.hs
=====================================
@@ -14,7 +14,6 @@ module GHC.Driver.Env
, hsc_HUG
, hsc_all_home_unit_ids
, hscUnitIndex
- , hscUIC
, hscUpdateLoggerFlags
, hscUpdateHUG
, hscInsertHPT
@@ -27,7 +26,7 @@ module GHC.Driver.Env
, runInteractiveHsc
, hscEPS
, hscEUD
- , hscEUDC
+ , hscUIC
, hscInterp
, prepareAnnotations
, discardIC
@@ -228,10 +227,7 @@ hscEPS :: HscEnv -> IO ExternalPackageState
hscEPS hsc_env = readIORef (euc_eps (ue_eps (hsc_unit_env hsc_env)))
hscEUD :: HscEnv -> IO (ExternalUnitDatabases UnitId)
-hscEUD = readExternalUnitDatabases . hscEUDC
-
-hscEUDC :: HscEnv -> ExternalUnitDatabaseCache UnitId
-hscEUDC hsc_env = ue_eud (hsc_unit_env hsc_env)
+hscEUD = readExternalUnitDatabases . hscUIC
hscUnitIndex :: HscEnv -> IO UnitIndex
hscUnitIndex hsc_env = ueUI (hsc_unit_env hsc_env)
=====================================
compiler/GHC/Driver/Session/Units.hs
=====================================
@@ -131,7 +131,7 @@ initMulti unitArgsFiles lintDynFlagsAndSrcs = do
home_unit_graph <- forM initial_home_graph $ \homeUnitEnv -> do
let hue_flags = homeUnitEnv_dflags homeUnitEnv
dflags = homeUnitEnv_dflags homeUnitEnv
- (unit_state,home_unit,mconstants) <- liftIO $ State.initUnits logger hue_flags (hscUIC hsc_env) (hscEUDC hsc_env) home_units
+ (unit_state,home_unit,mconstants) <- liftIO $ State.initUnits logger hue_flags (hscUIC hsc_env) home_units
updated_dflags <- liftIO $ updatePlatformConstants dflags mconstants
emptyHpt <- liftIO $ emptyHomePackageTable
=====================================
compiler/GHC/Unit/Env.hs
=====================================
@@ -178,19 +178,21 @@ data UnitEnv = UnitEnv
, ue_namever :: !GhcNameVersion
-- ^ GHC name/version (used for dynamic library suffix)
- , ue_eud :: {-# UNPACK #-} !(ExternalUnitDatabaseCache UnitId)
- -- ^ Global cache of already read package databases
-
, ue_uic :: {-# UNPACK #-} !UnitIndexCache
- -- ^ Index of already processed 'UnitInfo's.
- -- Shares state over all 'UnitState' in the 'HomeUnitGraph'.
+ -- ^ Global index of already processed external units.
+ -- Shares state over all 'UnitState's in the 'HomeUnitGraph'.
+ --
+ -- Allows sharing of 'UnitInfo's, ensuring each individual 'UnitInfo'
+ -- is retained a constant number of times.
+ --
+ -- See Note [Sharing 'UnitInfo's across the 'UnitEnv'] for details.
}
ueEPS :: UnitEnv -> IO ExternalPackageState
ueEPS = eucEPS . ue_eps
ueEUD :: UnitEnv -> IO (ExternalUnitDatabases UnitId)
-ueEUD = readExternalUnitDatabases . ue_eud
+ueEUD = readExternalUnitDatabases . ue_uic
ueUI :: UnitEnv -> IO UnitIndex
ueUI = readUnitIndex . ue_uic
@@ -199,7 +201,6 @@ ueUI = readUnitIndex . ue_uic
initUnitEnv :: UnitId -> HomeUnitGraph -> GhcNameVersion -> Platform -> IO UnitEnv
initUnitEnv cur_unit hug namever platform = do
eps <- initExternalUnitCache
- eud <- initExternalUnitDatabaseCache
uic <- initUnitIndexCache
return $ UnitEnv
{ ue_eps = eps
@@ -208,7 +209,6 @@ initUnitEnv cur_unit hug namever platform = do
, ue_current_unit = cur_unit
, ue_platform = platform
, ue_namever = namever
- , ue_eud = eud
, ue_uic = uic
}
=====================================
compiler/GHC/Unit/External/Database.hs
=====================================
@@ -1,18 +1,11 @@
module GHC.Unit.External.Database (
- -- * Mutable cache for 'ExternalUnitDatabases'
- ExternalUnitDatabaseCache (..),
- initExternalUnitDatabaseCache,
- readExternalUnitDatabases,
- readExternalUnitDatabase,
- cacheExternalUnitDatabase,
- clearExternalUnitDatabaseCache,
-- * 'ExternalUnitDatabases'
ExternalUnitDatabases,
emptyExternalUnitDatabases,
insertExternalUnitDatabases,
deleteExternalUnitDatabases,
lookupExternalUnitDatabases,
- -- * 'UnitDatabase'
+ -- * 'UnitDatabase' and how to merge them.
UnitDatabase (..),
mergeDatabases,
UnitPrecedenceMap,
@@ -20,8 +13,6 @@ module GHC.Unit.External.Database (
compareByPreference,
-- * Reading packages from disk.
UnitDbConfig (..),
- readOrGetUnitDatabase,
- readUnitDatabases,
readUnitDatabase,
getUnitDbRefs,
resolveUnitDatabase,
@@ -48,8 +39,6 @@ import GHC.Utils.Panic
import Control.Monad
import Data.Char
-import Data.IORef
-import Data.IORef qualified as IORef
import Data.List (sortBy)
import Data.Map.Strict (Map)
import Data.Map.Strict qualified as Map
@@ -60,40 +49,6 @@ import System.Directory
import System.Environment (getEnv)
import System.FilePath as FilePath
--- ----------------------------------------------------------------------------
--- ExternalUnitDatabaseCache
--- ----------------------------------------------------------------------------
-
--- | Mutable wrapper around 'ExternalUnitDatabases'.
-newtype ExternalUnitDatabaseCache unit = ExternalUnitDatabaseCache
- { eudc_databases :: IORef (ExternalUnitDatabases unit)
- }
-
-initExternalUnitDatabaseCache :: IO (ExternalUnitDatabaseCache unit)
-initExternalUnitDatabaseCache =
- ExternalUnitDatabaseCache <$> IORef.newIORef emptyExternalUnitDatabases
-
-readExternalUnitDatabases :: ExternalUnitDatabaseCache unit -> IO (ExternalUnitDatabases unit)
-readExternalUnitDatabases eudc =
- IORef.readIORef (eudc_databases eudc)
-
-modifyExternalUnitDatabaseCache :: ExternalUnitDatabaseCache unit -> (ExternalUnitDatabases unit -> ExternalUnitDatabases unit) -> IO ()
-modifyExternalUnitDatabaseCache eudc f =
- IORef.modifyIORef' (eudc_databases eudc) f
-
-readExternalUnitDatabase :: ExternalUnitDatabaseCache unit -> OsPath -> IO (Maybe (UnitDatabase unit))
-readExternalUnitDatabase eudc path = do
- dbs <- readExternalUnitDatabases eudc
- pure $ lookupExternalUnitDatabases path dbs
-
-cacheExternalUnitDatabase :: ExternalUnitDatabaseCache unit -> UnitDatabase unit -> IO ()
-cacheExternalUnitDatabase eudc db =
- modifyExternalUnitDatabaseCache eudc (insertExternalUnitDatabases db)
-
-clearExternalUnitDatabaseCache :: ExternalUnitDatabaseCache unit -> IO ()
-clearExternalUnitDatabaseCache eudc =
- modifyExternalUnitDatabaseCache eudc (const emptyExternalUnitDatabases)
-
-- ----------------------------------------------------------------------------
-- ExternalUnitDatabases
-- ----------------------------------------------------------------------------
@@ -230,12 +185,6 @@ data UnitDbConfig = UnitDbConfig
, unitDbConfigGHCDir :: FilePath
}
-readUnitDatabases :: Logger -> ExternalUnitDatabaseCache UnitId -> UnitDbConfig -> IO [UnitDatabase UnitId]
-readUnitDatabases logger db_cache cfg = do
- conf_refs <- getUnitDbRefs cfg
- confs <- liftM catMaybes $ mapM (resolveUnitDatabase cfg) conf_refs
- mapM (readOrGetUnitDatabase logger db_cache cfg) confs
-
getUnitDbRefs :: UnitDbConfig -> IO [PkgDbRef]
getUnitDbRefs cfg = do
let system_conf_refs = [UserPkgDb, GlobalPkgDb]
@@ -285,17 +234,6 @@ resolveUnitDatabase cfg UserPkgDb = runMaybeT $ do
if exist then return (OsPath.unsafeEncodeUtf pkgconf) else mzero
resolveUnitDatabase _ (PkgDbPath name) = return $ Just name
--- | Get the cached 'UnitDatabase' or read the 'UnitDatabase' at the given location.
-readOrGetUnitDatabase :: Logger -> ExternalUnitDatabaseCache UnitId -> UnitDbConfig -> OsPath -> IO (UnitDatabase UnitId)
-readOrGetUnitDatabase logger db_cache cfg conf_file =
- readExternalUnitDatabase db_cache conf_file >>= \ case
- Nothing -> do
- new_db <- readUnitDatabase logger cfg conf_file
- cacheExternalUnitDatabase db_cache new_db
- pure new_db
- Just db ->
- pure db
-
-- | Read the 'UnitDatabase' at the given location.
readUnitDatabase :: Logger -> UnitDbConfig -> OsPath -> IO (UnitDatabase UnitId)
readUnitDatabase logger cfg conf_file = do
=====================================
compiler/GHC/Unit/External/Index.hs
=====================================
@@ -6,12 +6,16 @@ module GHC.Unit.External.Index (
readUnitIndex,
modifyUnitIndexCache,
clearUnitIndexCache,
+ cacheExternalUnitDatabase,
+ readExternalUnitDatabases,
+ readExternalUnitDatabase,
-- * 'UnitIndex'
UnitIndex,
emptyUnitIndex,
wiringMap,
unwiringMap,
globalUnits,
+ externalUnitDatabases,
setWireMap,
wireMapExists,
addUnitInfoMap,
@@ -32,10 +36,14 @@ module GHC.Unit.External.Index (
updateWiredInUnits,
updateWiredInUnitsInUnitInfo,
updateWiredInUnitIdInModule,
+ -- * Reading external unit databases into the 'UnitIndexCache'
+ readOrGetUnitDatabase,
+ readUnitDatabases,
) where
import GHC.Prelude
+import GHC.Data.OsPath
import GHC.Data.ShortText qualified as ST
import GHC.Types.Unique.Map
import GHC.Unit.Database
@@ -46,17 +54,36 @@ import GHC.Unit.Info
import GHC.Unit.Types
import GHC.Utils.Logger
+import Control.Monad (liftM)
import Data.Either
import Data.IORef (IORef)
import Data.IORef qualified as IORef
import Data.Map.Strict (Map)
import Data.Map.Strict qualified as Map
+import Data.Maybe (catMaybes)
-- ----------------------------------------------------------------------------
-- UnitIndex
-- ----------------------------------------------------------------------------
-- | Mutable version of 'UnitIndex'.
+--
+-- The 'UnitIndexCache' ensures that all calls to 'initUnits' will
+-- share the 'UnitInfo' if it is possible.
+--
+-- To share the 'UnitInfo', it needs to be fully-resolved, i.e., its wired-in
+-- dependencies and modules need to be resolved.
+-- Thus, the 'UnitIndexCache' caches both the global 'WireMap' and the 'UnitInfoMap'.
+--
+-- The 'WireMap' is globally valid, as other parts of the compiler rely on the fact
+-- that only one instance of wired-in units is used.
+--
+-- Memory Invariant: The 'UnitIndexCache' is the root object for retaining fully-resolved
+-- 'UnitInfo'. 'UnitState' is expected to reference only 'UnitInfo's from the 'UnitIndexCache'.
+-- There is exactly one fully-resolved 'UnitInfo' alive for each external unit per unit database.
+--
+-- A second instance may or may not be stored in the 'externalUnitDatabases', which represent the
+-- in-memory cache of the on-disk unit databases.
newtype UnitIndexCache = UnitIndexCache
{ uic_index :: IORef UnitIndex
}
@@ -66,21 +93,41 @@ initUnitIndexCache =
UnitIndexCache <$> IORef.newIORef emptyUnitIndex
readUnitIndex :: UnitIndexCache -> IO UnitIndex
-readUnitIndex eudc =
- IORef.readIORef (uic_index eudc)
+readUnitIndex uic =
+ IORef.readIORef (uic_index uic)
modifyUnitIndexCache :: UnitIndexCache -> (UnitIndex -> UnitIndex) -> IO ()
-modifyUnitIndexCache eudc f =
- IORef.modifyIORef' (uic_index eudc) f
+modifyUnitIndexCache uic f =
+ IORef.modifyIORef' (uic_index uic) f
clearUnitIndexCache :: UnitIndexCache -> IO ()
-clearUnitIndexCache eudc =
- modifyUnitIndexCache eudc (const emptyUnitIndex)
+clearUnitIndexCache uic =
+ modifyUnitIndexCache uic (const emptyUnitIndex)
+
+cacheExternalUnitDatabase :: UnitIndexCache -> UnitDatabase UnitId -> IO ()
+cacheExternalUnitDatabase uic db =
+ modifyUnitIndexCache uic
+ (\ ui ->
+ ui
+ { ui_externalUnitDatabases = insertExternalUnitDatabases db (ui_externalUnitDatabases ui)
+ }
+ )
+
+readExternalUnitDatabases :: UnitIndexCache -> IO (ExternalUnitDatabases UnitId)
+readExternalUnitDatabases uic =
+ externalUnitDatabases <$> readUnitIndex uic
+
+readExternalUnitDatabase :: UnitIndexCache -> OsPath -> IO (Maybe (UnitDatabase UnitId))
+readExternalUnitDatabase uic path = do
+ dbs <- readExternalUnitDatabases uic
+ pure $ lookupExternalUnitDatabases path dbs
-- | Global index for external units that can be shared across multiple 'HomeUnitEnv's.
--
-- Allows sharing of the 'WireMap' and 'UnitInfo's that are stored in the 'UnitState'
-- of each 'HomeUnitEnv'.
+--
+-- See Note [Sharing 'UnitInfo's across the 'UnitEnv'] for details about memory usage.
data UnitIndex = UnitIndex
{ ui_wireMap :: !WireMap
-- ^ A mapping from database unit keys to wired in unit ids.
@@ -95,10 +142,13 @@ data UnitIndex = UnitIndex
, ui_unitInfoMap :: !GlobalUnitInfoMap
-- ^ A global map for all fully-resolved 'UnitInfo's.
--
- -- A 'UnitInfo' is fully-resolved, if its dependencies were updated to reference the
- -- wired-in packages (e.g., 'wiringMap') and the wired-in packages are updated.
- -- Further, the 'UnitInfo' is based on the 'ExternalUnitDatabases' results, resolving
- -- variables such as @${pkgroot}@ in paths.
+ -- See Note [Sharing 'UnitInfo's across the 'UnitEnv'] for more details
+ -- what we use this for and what a fully-resolved 'UnitInfo' is.
+ , ui_externalUnitDatabases :: !(ExternalUnitDatabases UnitId)
+ -- ^ Cache the already processed unit databases in-memory.
+ --
+ -- These 'GenericUnitInfo's have their paths resolved, e.g., no @${pkgroot}@ is
+ -- present any more.
}
-- | Get the 'WireMap'.
@@ -115,7 +165,18 @@ wiringMap = ui_wireMap
unwiringMap :: UnitIndex -> UnwireMap
unwiringMap = ui_unwireMap
+-- | Access the already processed unit databases.
+externalUnitDatabases :: UnitIndex -> ExternalUnitDatabases UnitId
+externalUnitDatabases = ui_externalUnitDatabases
+
-- | Access the global map of fully-resolved 'UnitInfo's.
+--
+-- A 'UnitInfo' is fully-resolved, if its dependencies were updated to reference the
+-- wired-in packages (e.g., 'wiringMap') and the wired-in packages are updated.
+-- Further, the 'UnitInfo' is based on the 'ExternalUnitDatabases' results, resolving
+-- variables such as @${pkgroot}@ in paths.
+--
+-- See Note [Sharing 'UnitInfo's across the 'UnitEnv'] for why this is helpful.
globalUnits :: UnitIndex -> GlobalUnitInfoMap
globalUnits = ui_unitInfoMap
@@ -124,6 +185,7 @@ emptyUnitIndex = UnitIndex
{ ui_wireMap = emptyWireMap
, ui_unwireMap = emptyUnwireMap
, ui_unitInfoMap = emptyGlobalUnitInfoMap
+ , ui_externalUnitDatabases = emptyExternalUnitDatabases
}
-- | Set the 'WireMap' of 'UnitIndex'.
@@ -167,7 +229,8 @@ type UnitAbiHash = ST.ShortText
--
-- However, a user can choose a conflicting 'UnitId', causing a conflict after all.
-- We use the 'UnitAbiHash' for disambiguation. If both 'UnitId' and 'UnitAbiHash' are
--- identical in separate unit databases, we can assume they are the same unit.
+-- identical in separate unit databases, we can assume they are the same unit, according
+-- to the documentation of GHC.
newtype GlobalUnitInfoMap = GlobalUnitInfoMap (UniqMap UnitId (Map UnitAbiHash UnitInfo))
-- | Lookup the 'UnitInfo' in the 'GlobalUnitInfoMap'.
@@ -310,3 +373,23 @@ upd_wired_in :: WireMap -> UnitId -> UnitId
upd_wired_in wiredInMap key
| Just key' <- lookupWireMap key wiredInMap = key'
| otherwise = key
+
+-- -----------------------------------------------------------------------------
+-- Reading the unit database(s) into the 'UnitIndexCache'
+
+readUnitDatabases :: Logger -> UnitIndexCache -> UnitDbConfig -> IO [UnitDatabase UnitId]
+readUnitDatabases logger db_cache cfg = do
+ conf_refs <- getUnitDbRefs cfg
+ confs <- liftM catMaybes $ mapM (resolveUnitDatabase cfg) conf_refs
+ mapM (readOrGetUnitDatabase logger db_cache cfg) confs
+
+-- | Get the cached 'UnitDatabase' or read the 'UnitDatabase' at the given location.
+readOrGetUnitDatabase :: Logger -> UnitIndexCache -> UnitDbConfig -> OsPath -> IO (UnitDatabase UnitId)
+readOrGetUnitDatabase logger db_cache cfg conf_file =
+ readExternalUnitDatabase db_cache conf_file >>= \ case
+ Nothing -> do
+ new_db <- readUnitDatabase logger cfg conf_file
+ cacheExternalUnitDatabase db_cache new_db
+ pure new_db
+ Just db ->
+ pure db
=====================================
compiler/GHC/Unit/State.hs
=====================================
@@ -6,7 +6,6 @@ module GHC.Unit.State (
module GHC.Unit.Info,
-- * Reading the package config, and processing cmdline args
UnitState(..),
- TrustOverlay(..),
UnitDatabase (..),
UnitErr (..),
emptyUnitState,
@@ -16,6 +15,13 @@ module GHC.Unit.State (
getUnitDbRefs,
resolveUnitDatabase,
listUnitInfo,
+ -- * Overlays over the unit set
+ TrustOverlay,
+ IsTrusted(..),
+ lookupTrustOverlay,
+ distrustUnits,
+ trustUnits,
+ emptyTrustOverlay,
-- * Querying the package config
lookupUnit,
lookupUnit',
@@ -252,12 +258,19 @@ data IsTrusted
| Distrusted
deriving ( Eq, Ord )
+-- | The 'TrustOverlay' stores user overwrites of the on-disk 'unitIsTrusted' status.
+--
+-- The user can overwrite this value via flags such as @-distrust-all-packages@.
+-- We do not modify the 'UnitInfo' directory, but rather store this user selection
+-- in the 'TrustOverlay'.
+--
+-- This allows us to share the 'UnitInfo' completely and saves us memory.
newtype TrustOverlay = TrustOverlay
{ trustOverlay :: UniqMap UnitId IsTrusted
}
lookupTrustOverlay :: TrustOverlay -> UnitId -> Maybe IsTrusted
-lookupTrustOverlay (TrustOverlay to) = lookupUniqMap to
+lookupTrustOverlay to = lookupUniqMap (trustOverlay to)
distrustUnits :: [UnitId] -> TrustOverlay -> TrustOverlay
distrustUnits elements (TrustOverlay to) = TrustOverlay $ foldl' (\ acc uid -> addToUniqMap acc uid Distrusted) to elements
@@ -268,6 +281,52 @@ trustUnits elements (TrustOverlay to) = TrustOverlay $ foldl' (\ acc uid -> addT
emptyTrustOverlay :: TrustOverlay
emptyTrustOverlay = TrustOverlay emptyUniqMap
+{-
+Note [Sharing 'UnitInfo's across the 'UnitEnv']
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The 'UnitState' and 'UnitIndex' are closely related.
+
+The 'UnitState' stores all information about the external units referenced by
+a single HomeUnitEnv.
+This includes in particular the 'unitInfoMap', an in-memory representation of
+the unit databases that a 'HomeUnitEnv' depends on.
+Multiple home units can depend on the same unit database, leading to a linear
+increase of 'UnitInfo's per 'HomeUnitEnv'. (It used to be quadratic even, due
+to accidentally retaining old 'UnitInfo's.)
+Thus, we want to share the 'UnitInfo' across multiple 'HomeUnitEnv's.
+This where the 'UnitIndex' is needed.
+
+The 'UnitIndex' stores all fully-resolved 'UnitInfo's that can be referenced
+by the 'UnitState'.'unitInfoMap'.
+We consider a 'UnitInfo' as fully-resolved, if its dependencies were updated to reference the
+wired-in units (e.g., 'wiringMap') and the wired-in units are updated as well.
+See Note [Wired-in units] for more details on wired-in units.
+Further, the 'UnitInfo' is based on the 'ExternalUnitDatabases' results, resolving
+variables such as @${pkgroot}@ in paths.
+
+As such, we can consider the 'UnitIndex' to be global data that is referenced by
+the 'UnitState' for better sharing of 'UnitInfo's.
+
+In fact, using the 'UnitIndex', we can impose a hard upper bound on the number
+of live 'UnitInfo's in a GHC session:
+
+> For each on-disk 'GenericUnitInfo', there are at most two objects alive.
+
+One instance is stored in 'ExternalUnitDatabases' where variables are resolved,
+but the wired-in units haven't been resolved.
+
+The second instance is the fully-resolved 'UnitInfo' stored in the 'UnitIndex'.
+-}
+
+-- | The 'UnitState' contains a plethora of information local to a single 'HomeUnitEnv'.
+--
+-- It stores module visibilities, unit trust for @SafeHaskell@, available units for error messages,
+-- explicit unit dependencies and knows how to instantiate backpack signature and holes
+-- on demand.
+--
+-- A 'HomeUnitEnv' should rarely/never have to look into the 'UnitIndex', all external
+-- unit related information is stored in the 'UnitState'.
+--
data UnitState = UnitState {
-- | A mapping of 'Unit' to 'UnitInfo'. This list is adjusted
-- so that only valid units are here. 'UnitInfo' reflects
@@ -276,6 +335,7 @@ data UnitState = UnitState {
-- may have the 'exposed' flag be 'False'.)
--
-- All values are shared with 'UnitIndex'.'globalUnits'.
+ -- See Note [Sharing 'UnitInfo's across the 'UnitEnv'] for details.
unitInfoMap :: UnitInfoMap,
-- | Set of units that we trust.
@@ -283,7 +343,10 @@ data UnitState = UnitState {
-- Local overlay of 'UnitInfo'.
-- This avoids modifying the 'UnitInfo' directly, potentially saving
-- a lot of duplication.
- trustedUnits :: TrustOverlay,
+ --
+ -- We keep this in WHNF as it is relatively cheap but could easily retain
+ -- references to bigger structures.
+ trustedUnits :: !TrustOverlay,
-- | A mapping of 'PackageName' to 'UnitId'. If several units have the same
-- package name (e.g. different instantiations), then we return one of them...
@@ -333,8 +396,6 @@ emptyUnitState = UnitState {
unitInfoMap = emptyUniqMap,
trustedUnits = emptyTrustOverlay,
packageNameMap = emptyUFM,
- -- wireMap = emptyUniqMap,
- -- unwireMap = emptyUniqMap,
preloadUnits = [],
explicitUnits = [],
homeUnitDepends = Set.empty,
@@ -439,14 +500,16 @@ isUnitInfoTrusted ue u =
-- 'initUnits' can be called again subsequently after updating the
-- 'packageFlags' and 'packageDBFlags' fields of the 'DynFlags', and it will
-- update the 'unitState' in 'DynFlags'.
-initUnits :: Logger -> DynFlags -> UnitIndexCache -> ExternalUnitDatabaseCache UnitId -> Set.Set UnitId -> IO (UnitState, HomeUnit, Maybe PlatformConstants)
-initUnits logger dflags unit_index cached_dbs home_units = do
+--
+-- Also, see Note [Sharing 'UnitInfo's across the 'UnitEnv'] for implementation details.
+initUnits :: Logger -> DynFlags -> UnitIndexCache -> Set.Set UnitId -> IO (UnitState, HomeUnit, Maybe PlatformConstants)
+initUnits logger dflags unit_index home_units = do
let forceUnitInfoMap state = unitInfoMap state `seq` ()
unit_state <- withTiming logger (text "initializing unit database")
forceUnitInfoMap
- $ mkUnitState logger unit_index cached_dbs (initUnitConfig dflags home_units)
+ $ mkUnitState logger unit_index (initUnitConfig dflags home_units)
putDumpFileMaybe logger Opt_D_dump_mod_map "Module Map"
FormatText (updSDocContext (\ctx -> ctx {sdocLineLength = 200})
@@ -638,10 +701,9 @@ reportCycles logger sccs = when (logVerbAtLeast logger 2) $ mapM_ report sccs
mkUnitState
:: Logger
-> UnitIndexCache
- -> ExternalUnitDatabaseCache UnitId
-> UnitConfig
-> IO UnitState
-mkUnitState logger unit_index db_cache cfg = do
+mkUnitState logger unit_index cfg = do
{-
Plan.
@@ -695,7 +757,7 @@ mkUnitState logger unit_index db_cache cfg = do
we build a mapping saying what every in scope module name points to.
-}
- dbs <- readUnitDatabases logger db_cache (initUnitDbConfig cfg)
+ dbs <- readUnitDatabases logger unit_index (initUnitDbConfig cfg)
-- distrust all units if the flag is set
let distrustUnitsOfDb overlay db = foldl' (\ acc ui -> distrustUnits [unitId ui] acc) overlay (unitDatabaseUnits db)
@@ -713,7 +775,7 @@ mkUnitState logger unit_index db_cache cfg = do
debugTraceMsg logger 2 $
text "package flags" <+> ppr other_flags
- let !home_unit_deps = selectHomeUnits (unitConfigHomeUnits cfg) hpt_flags
+ let home_unit_deps = selectHomeUnits (unitConfigHomeUnits cfg) hpt_flags
-- Merge databases together, without checking validity
(pkg_map1, prec_map) <- mergeDatabases logger dbs
@@ -727,7 +789,7 @@ mkUnitState logger unit_index db_cache cfg = do
-- Compute trust flags (these flags apply regardless of whether
-- or not packages are visible or not)
- !trustUnitsOverlay <- mayThrowUnitErr
+ trustUnitsOverlay <- mayThrowUnitErr
$ foldM (applyTrustFlag prec_map unusable (nonDetEltsUniqMap pkg_map2))
distrustedUnitsOverlay (reverse (unitConfigFlagsTrusted cfg))
let pkgs1 = nonDetEltsUniqMap pkg_map2
@@ -769,12 +831,12 @@ mkUnitState logger unit_index db_cache cfg = do
-- Note: we NEVER expose indefinite packages by
-- default, because it's almost assuredly not
-- what you want (no mix-in linking has occurred).
- let !x = fsPackageName p in if unitIsExposed p && unitIsDefinite (mkUnit p) && mostPreferable p
+ if unitIsExposed p && unitIsDefinite (mkUnit p) && mostPreferable p
then addToUniqMap vm (mkUnit p)
UnitVisibility {
uv_expose_all = True,
uv_renamings = [],
- uv_package_name = First (Just x),
+ uv_package_name = First (Just $ fsPackageName p),
uv_requirements = emptyUniqMap,
uv_explicit = Nothing
}
=====================================
ghc/GHCi/UI.hs
=====================================
@@ -857,7 +857,7 @@ installInteractiveHomeUnits dflags = do
env <- GHC.getSession
let unit_index = hscUIC env
(unit_state,home_unit,_mconstants) <-
- liftIO $ initUnits logger dflags unit_index (hscEUDC env) all_home_units
+ liftIO $ initUnits logger dflags unit_index all_home_units
hpt <- liftIO emptyHomePackageTable
pure (HUG.mkHomeUnitEnv unit_state dflags hpt (Just home_unit))
=====================================
testsuite/tests/driver/TUnitInfo/generic-unit-info-space-mhu.stdout
=====================================
@@ -0,0 +1,2 @@
+### Heap Census
+There are exactly two GenericUnitInfo closures alive per on-disk package
=====================================
testsuite/tests/driver/TUnitInfo/generic-unit-info-space.hs
=====================================
@@ -87,7 +87,7 @@ initGhcM numOfPkgs xs = do
-- If this number changes without a good reason, DO NOT ACCEPT THE CHANGES, you have introduced a space leak.
-- We say less than the expected size is accepted, because in the multiple-home-units case, we don't force the second
-- UnitInfo closure enough after initial processing.
- when (num <= expectedSizeInBytes) $ do
+ when (num > expectedSizeInBytes) $ do
putStrLn "Space leak detected by generic-unit-info-space test:"
putStrLn $ (show (num `div` genericUnitInfoSizeInBytes)) ++ " live GenericUnitInfo when <= (" ++ show expectedNumberOfUnitInfos ++ ") are expected"
readFile hpFile >>= putStrLn
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d4247f659925671ed5a4259e1ea584…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d4247f659925671ed5a4259e1ea584…
You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
1
0
[Git][ghc/ghc][wip/andreask/arm-ffi] 53 commits: hadrian: binary-dist-dir should not be the default target
by Andreas Klebinger (@AndreasK) 21 Jul '26
by Andreas Klebinger (@AndreasK) 21 Jul '26
21 Jul '26
Andreas Klebinger pushed to branch wip/andreask/arm-ffi at Glasgow Haskell Compiler / GHC
Commits:
2ecabb4f by Zubin Duggal at 2026-07-09T09:23:25-04:00
hadrian: binary-dist-dir should not be the default target
Revert behaviour to pre 23c9b6c392f52ec9d7a8618b204ff6b885f5fba2
In 23c9b6c392f52ec9d7a8618b204ff6b885f5fba2, we applied the following behaviour change:
```
hadrian: Build stage 2 cross compilers
...
* hadrian: Make binary-dist-dir the default build target. This allows us
to have the logic in one place about which libraries/stages to build
with cross compilers. Fixes #24192
```
This is a major regression to development experience, a plain hadrian/build
--freeze1 now takes ages because we rebuild all docs (which need to go in the
binary dist dir).
`binary-dist-dir` is the wrong default target for regular GHC development work
Fixes #27445
- - - - -
e16388e3 by Zubin Duggal at 2026-07-09T09:23:25-04:00
.gitignore: Add the hadrian system.config introduced by commit 23c9b6c392f52ec9d7a8618b204ff6b885f5fba2
Since
commit 23c9b6c392f52ec9d7a8618b204ff6b885f5fba2
Author: Matthew Pickering <matthewtpickering(a)gmail.com>
Date: Thu Dec 21 16:17:41 2023 +0000
hadrian: Build stage 2 cross compilers
./configure produces /hadrian/cfg/system.config.{host,target}
Add these to .gitignore
- - - - -
7e8abf41 by Alan Zimmerman at 2026-07-09T09:24:12-04:00
EPA: Replace AnnListItem with simply [TrailingAnn]
Remove the unnecessary wrapper around a single field.
- - - - -
29032f17 by Zubin Duggal at 2026-07-09T09:24:58-04:00
testsuite: Keep real reason for fragile test failures
- - - - -
c34e03a7 by Zubin Duggal at 2026-07-09T09:24:58-04:00
testsuite: Fall back to the failure reason for empty JUnit bodies
- - - - -
409d40f0 by Zubin Duggal at 2026-07-09T09:24:58-04:00
testsuite: Show output diffs in JUnit output
Also refactor compare_outputs to return essentially a `Maybe Diff`
(`CompareOutput`) instead of a bool, but more pythonic. This
allows us to pass the diff through nice.
- - - - -
06fee1ab by Zubin Duggal at 2026-07-09T09:24:58-04:00
perf notes: include stat deviation and acceptance window in notes so they show up in gitlab
- - - - -
57c0f32c by mangoiv at 2026-07-10T11:08:38-04:00
driver: enable -finter-module-far-jumps by default
this fixes a compatibility bug with certain binutils/gcc versions where
we were seeing jump offset overflow errors.
This commit can probably reverted if we stop supporting the problematic
binutils/gcc verions (2.44 and 14.2, respectively)
Reolves #26994
- - - - -
4396a6f2 by Andrea Vezzosi at 2026-07-10T11:09:25-04:00
[Fix #27287] preserve ModBreaks in ModIface
- - - - -
ed261a7e by Cheng Shao at 2026-07-14T17:59:38-04:00
hadrian: fix HLS support
This patch fixes hadrian's HLS support so one can rely on HLS when
working on the hadrian codebase. Fixes #27480.
Not building/linking shared libraries for hadrian is a severely
premature optimization; this top-level setting in `cabal.project` only
affects home packages while the dependencies in the cabal store are
built with vanilla/dynamic anyway, and even adding dynamic builds to
home packages would not be costly due to cabal's usage of
`-dynamic-too`.
- - - - -
eee8ec5b by Cheng Shao at 2026-07-14T18:00:20-04:00
compiler: fix miscompiled %load_relaxed, add missing %store_relaxed
This patch fixes the %load_relaxed cmm primop compilation logic to
correctly use relaxed memory ordering, and adds the missing
%store_relaxed primop. Parsing logic of %load/%store with explicit
ordering is covered in the AtomicFetch test case. Fixes #27483.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
1718230f by Alan Zimmerman at 2026-07-14T18:01:06-04:00
EPA: Keep binds and sigs together in HsValBindsLR
We combine them into a single list for GhcPs, wrapped in the
ValBind data type, which is the bind equivalent of ValD, having
constructors for binds and sigs.
This simplifies exact print processing, especially when using it to
update the contents of local binds, as we no longer need AnnSortKey
BindTag
- - - - -
6bd1ad2a by Andreas Klebinger at 2026-07-14T18:01:49-04:00
Bump nofib submodule to account for MonoLocalBinds.
New versions of GHC enable MonoLocalBinds by default.
This breaks some of the benchmarks. I've fixed this and
this bump pulls in that fix.
- - - - -
7eb0f1c9 by Cheng Shao at 2026-07-14T18:02:31-04:00
testsuite: fix bytecodeIPE test under +ipe flavours
This patch fixes the bytecodeIPE test under +ipe flavours. It used to
fail under +ipe because the RTS is built with IPE info, then
stg_AP_info in RTS carries IPE info, so whereFrom wouldn't return
Nothing. Now the test checks IPE info of a datacon in the ghci-loaded
module which is not affected by whether the RTS is built with IPE info
or not. Fixes #27498.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
ef038aae by cydparser at 2026-07-15T04:35:41-04:00
Reduce bytes allocated for `capabilities` in RTS (fixes #27487)
In rts/Capability.c, `capabilities` is an array of pointers, but it was allocated as if it were an
array of Capability's.
- - - - -
d377e83e by Cheng Shao at 2026-07-15T04:36:27-04:00
rts: fix missing UNTAG in stg_readTVarIOzh
This patch fixes missing UNTAG on the current value closure read from
StgTVar. UNTAG is a no-op when it's stg_TREC_HEADER_info which is word
aligned; it may be a tagged closure, and reading info table from the
tagged address is an unaligned load which may cause issues on
platforms with strict alignment requirements.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
8ed03842 by Cheng Shao at 2026-07-15T04:36:27-04:00
rts: fix missing UNTAG in stg_control0zh_ll
This patch fixes missing UNTAG on the cont closure returned by
captureContinuationAndAbort. In case it's not NULL,
captureContinuationAndAbort returns a tagged StgContinuation closure,
in which case it must be untagged before accessing the
apply_mask_frame field.
In the past it worked out of luck: when apply_mask_frame was NULL then
mask_frame_offset is also 0 so the control flow didn't diverge to a
wrong path. Still, this is horribly wrong and will crash once
StgContinuation struct is refactored and fields are shuffled around.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
5aa7000a by Cheng Shao at 2026-07-15T04:37:08-04:00
compiler: fix redundant AP thunk codegen when not using -ticky-ap-thunk
This patch fixes a double negation confusion in !7525 that results in
some redundant AP thunk code generation when not using
-ticky-ap-thunk. Now, we use `stgToCmmUseStdApThunk` to indicate
whether precomputed AP thunks in the RTS should be used, which
defaults to `True`, unless `-ticky-ap-thunk` is passed.
`-finfo-table-map` now also implies `-ticky-ap-thunk`, since when
doing IPE profiling we want the generated AP thunks to be unique.
Fixes #27502.
-------------------------
Metric Decrease:
T3064
-------------------------
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
d43a7b7a by Brian McKenna at 2026-07-15T20:10:04+02:00
Strip ticks when desugaring bool guards
The special `considerAccessible` pattern was broken when compiling
with debug info. Compiling with debug info wraps expressions with
`SourceNote` ticks, which broke the internals of the
`desugarBoolGuard` function. Ticks are now ignored within this
function.
Fixes #27360
- - - - -
ede4b17b by Ben Gamari at 2026-07-15T22:59:53-04:00
base: Display ExceptionContext in WhileHandling's textual description
As originally-implemented the implementation for
`WhileHandling(displayExceptionAnnotation)` would display the
`ExceptionContext` of the exception which it carries (as this was the
behavior of `displayException`, in terms of which
`displayExceptionAnnotation` was implemented).
However, in 284ffab3 the definition of `SomeException(displayException)`
was changed to exclude the `ExceptionContext`. This means that
`WhileHandling(displayExceptionAnnotation)` fails to describe the
provenance of the exception which it captures, greatly limiting its
utility.
Return the implementation to its originally-specified behavior by
implementing `WhileHandling(displayExceptionAnnotation)` in terms of
`displayExceptionWithInfo`.
Fixes #27456.
- - - - -
0f64f348 by Cheng Shao at 2026-07-16T15:41:08+00:00
ci: add missing docker permission workaround in abi-test job
- - - - -
660cb239 by Cheng Shao at 2026-07-16T19:37:48+00:00
bindist: Fix make install -j race condition on macos/freebsd
This patch fixes make install -j race condition on macos/freebsd. BSD
install fails with EEXIST when multiple install processes concurrently
create the same prefix directory. So we add an `install_dirs`
prerequisite job that sequentially creates the directories for
subsequent jobs to work with. Fixes #27499.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
08130257 by Cheng Shao at 2026-07-16T19:37:48+00:00
ci: run bindist make install with -j
This patch makes the ci scripts run `make install` with `-j` to reduce
wall clock time when installing the bindist, see related issue for
benchmark numbers. This only affects ghc ci logic, the user-facing
default is up to distributors and is still `-j1`. Closes #27029.
- - - - -
d5ae6906 by Adam Gundry at 2026-07-17T04:57:43-04:00
Mark various language extension flags as deprecated (see #27329)
The following language extensions are now deprecated:
- AlternativeLayoutRule
- AlternativeLayoutRuleTransitional
- ParallelArrays
- PolymorphicComponents
- Rank2Types
In addition, the warning `-Walternative-layout-rule-transitional`
has been marked as deprecated, as it is emitted only under the
deprecated extension `XAlternativeLayoutRuleTransitional`.
- - - - -
fe3b059c by Andrew Lelechenko at 2026-07-17T04:58:26-04:00
base: re-export GHC.Environment.getFullArgs from System.Environment
CLC proposal https://github.com/haskell/core-libraries-committee/issues/431
- - - - -
722236dd by sheaf at 2026-07-18T08:48:31-04:00
Coercion optimisation: avoid double-Sym for InstCo
Ticket #27374 pointed out an issue with GHC.Core.Coercion.Opt.optCoercion's
handling of InstCo: it contravened (LC2) in Note [The LiftingContext in optCoercion]
because it applied the ambient 'sym' to a coercion that was then added
to the lifting context substitution.
Fixes #27374
Co-authored-by: Simon Jakobi <simon.jakobi(a)gmail.com>
- - - - -
ff70fc75 by sheaf at 2026-07-18T08:48:31-04:00
Coercion optimisation: avoid exponential behaviour
The change to coercion optimisation of 'InstCo' in the previous commit
introduces exponential behaviour to the coercion optimiser. To avoid
this, this commit provides a way to push in 'Sym' of an already-optimised
coercion: GHC.Core.Coercion.Opt.mkDeepSymCo.
See Note [Pushing Sym without re-optimising] in GHC.Core.Coercion.Opt.
- - - - -
dfef27f0 by Duncan Coutts at 2026-07-18T08:49:12-04:00
Move THREADED_RTS-conditional struct members to end of Capability
Accessing members of the Capability struct from CMM code rely on
accessor macros. (The macros are generated by deriveConstants).
These macros have a single definition. This means that the offsets of
all struct members must *not* vary based on THREADED_RTS vs
!THREADED_RTS. This requires that any struct members that are
conditional on THREADED_RTS must occur after the unconditional struct
members. Hence we move all the ones that are conditional on
THREADED_RTS to the end.
Add a deriveConstants entry for the iomgr member of the Capability
struct, which was the motivation for this change.
Add warning messages to help our future selves. Debugging this took me
a couple hours in gdb!
- - - - -
c254e022 by Duncan Coutts at 2026-07-18T08:49:12-04:00
Make the IOManager API use CapIOManager rather than Capability
This makes the API somewhat more self-contained and more consistent.
Now the IOManager API and each of the backends takes just the I/O
manager structure. Previously we had a bit of a mixture, depending on
whether the function needed access to the Capability or just the
CapIOManager.
We still need access to the cap, so we introduce a back reference to
reach the capability, via iomgr->cap.
Convert all uses in select and poll backends, but not win32 ones.
Convert callers in the scheduler and elsewhere.
Also convert the three CMM primops that call IOManager APIs. They just
need to use Capability_iomgr(MyCapability()).
- - - - -
4f3d8f31 by Duncan Coutts at 2026-07-18T08:49:12-04:00
Split posix/MIO.c out of posix/Signals.c
The MIO I/O manager was secretly living inside the Signals file.
Now it gets its own file, like any other self-respecting I/O manager.
- - - - -
52ce04a9 by Duncan Coutts at 2026-07-18T08:49:12-04:00
Rationalise some scheduler run queue utilities
Move them all to the same place in the file.
Make some static that were used only internally.
Also remove a redundant assignment after calling truncateRunQueue that
is already done within truncateRunQueue.
- - - - -
75bbdebc by Duncan Coutts at 2026-07-18T08:49:12-04:00
Rename initIOManager{AfterFork} to {re}startIOManager
These are more accurate names, since these actions happen after
initialisation and are really about starting (or restarting) background
threads.
- - - - -
724c0517 by Duncan Coutts at 2026-07-18T08:49:12-04:00
Free per-cap I/O managers during shutdown and forkProcess
Historically this was not strictly necessary. The select and win32
legacy I/O managers did not maintain any dynamically allocated
resources. The new poll one does (an auxillary table), and so this
should be freed.
After forkProcess, all threads get deleted. This includes threads
waiting on I/O or timers. So as of this patch, resetting the I/O
manager is just about tidying things up. For example, for the poll
I/O manager this will reset the size of the AIOP table (which
otherwise grows but never shrinks).
In future however the re-initialising will become neeecessary for
functionality, since some I/O managers will need to re-initialise
wakeup fds that are set CLOEXEC.
- - - - -
c007d122 by Duncan Coutts at 2026-07-18T08:49:12-04:00
Add a TODO to the MIO I/O manager
The direction of travel is to make I/O managers per-capability and have
all their state live in the struct CapIOManager. The MIO I/O manager
however still has a number of global variables.
It's not obvious how handle these globals however.
- - - - -
b65ab7b3 by Duncan Coutts at 2026-07-18T08:49:12-04:00
Add a FIXME note in the Poll I/O manager
- - - - -
daf2bd6f by Duncan Coutts at 2026-07-18T08:49:12-04:00
Add missing updateRemembSetPushClosure in poll I/O manager
For the non-moving GC.
- - - - -
e33ca830 by Duncan Coutts at 2026-07-18T08:49:12-04:00
Minor doc improvement to struct StgAsyncIOOp member outcome
Mention the enumeration names, as well as their numeric values. The rest
of the code uses the enum names.
- - - - -
4edd2579 by Duncan Coutts at 2026-07-18T08:49:12-04:00
Minor doc improvements for StgTSOBlockInfo
Clarify that certain union members are used only by certain legacy
I/O managers. Hopefully we will be able to remove these at some point.
- - - - -
536bedbb by Duncan Coutts at 2026-07-18T08:49:12-04:00
Avoid exporting various win32-specific rts symbols
The BeginPrivate.h / EndPrivate.h scheme works perfectly well on
Windows, but all of the rts/win32/*.h files were not using it.
- - - - -
8139b5ac by Duncan Coutts at 2026-07-18T08:49:12-04:00
Remove wakeupIOManager, ioManagerWakeup and setIOManagerWakeupFd
We no longer need wakeupIOManager for the threaded RTS case, so we can
remove it and the bits only needed to support it. This includes the
pipe/eventfd fd shared between the RTS and the in-library I/O manager
used for waking up the I/O manager thread. The pipe/eventfd still
exists, but it no longer has to be communicated to the RTS, since the
RTS no longer needs to use it.
So we remove the RTS API export setIOManagerWakeupFd, and remove uses of
it within the I/O managers in ghc-internal.
- - - - -
74fe7c66 by Duncan Coutts at 2026-07-18T08:49:12-04:00
Add a new interruptIOManager API for the I/O managers
It will be used to interrupt awaitCompletedTimeoutsOrIO. Also update the
return type and docs for awaitCompletedTimeoutsOrIO to have it return
false when it gets interrupted, and have no useful post condition in
that case.
- - - - -
38792843 by Duncan Coutts at 2026-07-18T08:49:13-04:00
Add interruptIOManager support for select I/O manager
Uses the FdWakup mechanism.
- - - - -
2f3b00aa by Duncan Coutts at 2026-07-18T08:49:13-04:00
Add interruptIOManager support for poll I/O manager
Uses the FdWakup mechanism.
A quirk we have to cope with is that we now need to poll one more fd --
the wakeup_fd_r -- but this fd has no corresponding entry in the
aiop_table. This is awkward since we have set up our aiop_poll_table to
be an auxilliary table with matching indicies.
The solution this patch uses (and described in the comments) is to have
two tables: struct pollfd *aiop_poll_table, *full_poll_table;
and to have the aiop_poll_table alias the tail of the full_poll_table.
The head entry in the full_poll_table is the extra fd. So we poll the
full_poll_table, while the aiop_poll_table still has matching indicies
with the aiop_table.
Hurrah for C aliasing rules.
- - - - -
cee50131 by Duncan Coutts at 2026-07-18T08:49:13-04:00
Add interruptIOManager support for win32 legacy I/O manager
And remove unused related helper resetAbandonRequestWait. It is not
called because the event is created in auto-reset mode, so never needs
to be reset manually.
- - - - -
cf453143 by Duncan Coutts at 2026-07-18T08:49:13-04:00
Note lack of interruptIOManager support for WinIO I/O manager
Though there's a plausible design, we can't sanely test it at the moment
due to related WinIO bugs. Filed as issue #27403.
- - - - -
1b74a0ad by Duncan Coutts at 2026-07-18T08:49:13-04:00
Be more explicit about enum IOReadOrWrite values, and type within cmm
Belt and braces.
- - - - -
b388d093 by Brian McKenna at 2026-07-18T17:51:50-04:00
Ignore ticks in the pattern-match term oracle
The term-oracle in the pattern-match checker is keyed by a canonical
form of the scrutinee, computed by `makeDictsCoherent`. That canonical
form was tick-sensitive: two occurrences of an otherwise identical
expression that happened to carry different ticks were treated as
distinct values, breaking long-distance information.
This shows up in practice under `-finfo-table-map`, because the
desugarer wraps every record-selector use site in a `SourceNote`
carrying that site's span. For example:
data Box = Box { unBox :: Maybe Int }
f b = case unBox b of
Nothing -> 0
Just _ -> let Just x = unBox b in x
The two `unBox b` expressionss carry different SourceNote spans, the
pattern-match checker sees them as different, the long-distance
information from the outer `Just _` branch never reaches the
let-pattern, and `Just x = unBox b` is wrongly reported as
non-exhaustive.
We now strip all ticks in `makeDictsCoherent`. This is documented as
Wrinkle (UD1) of Note [Unique dictionaries in the TmOracle CoreMap].
Fixes #27314
- - - - -
c23e1acb by Mrjtjmn at 2026-07-18T17:52:45-04:00
Add explanations for unsolved Typeable constraints
This commit adds explanations for unsolved 'Typeable' constraints.
GHC will now provide additional explanations for an unsolved constraint
of the form 'Typeable ty', explain why GHC did not solve Typeable constraint.
e.g.:
- 'ty' is a polymorphic type (e.g. forall a. a -> a)
- 'ty' is a qualified type (e.g. Eq Int => Int)
- 'ty' is an unboxed sum type
- 'ty' is an unreduced type family application
- 'ty' whose kind is not typeable
Fixes #26532
- - - - -
cbef021e by Artem Pelenitsyn at 2026-07-19T07:49:55-04:00
ghc-internal: Lock.hs: fix typo and indentation
- - - - -
42918646 by Duncan Coutts at 2026-07-19T07:50:36-04:00
Fix failing test GcStaticPointers for non-moving GC
Minor mistake in asserting something before checking for that same
thing.
Specifically, Bdescr asserts HEAP_ALLOCED_GC, but Bdescr was being used
prior to a guard that checks HEAP_ALLOCED_GC. The solution is just to
move the use of Bdescr after the guard.
Thanks to Simon Jakobi for identifying the problem.
- - - - -
16046e69 by Andreas Klebinger at 2026-07-21T15:53:42+02:00
cmm: Add machop width info with -dppr-debug for infix ops.
- - - - -
13f7d159 by Andreas Klebinger at 2026-07-21T15:53:42+02:00
Add test for #27430.
- - - - -
28318419 by Andreas Klebinger at 2026-07-21T15:53:42+02:00
arm64 ncg: Fix subword handling of ffi calls.
Our invariants require us to clear the high bits for subword results.
We now do so both for unspecified bit casts (MO_CONV_XX) and when
taking in results from ffi calls.
I also renamed truncateReg to make it clear it changes the register.
- - - - -
235 changed files:
- .gitignore
- .gitlab-ci.yml
- .gitlab/ci.sh
- + changelog.d/T26532
- + changelog.d/T27314.md
- + changelog.d/T27329
- + changelog.d/T27360
- + changelog.d/T27374
- + changelog.d/T27430
- + changelog.d/T27456
- + changelog.d/fix-cmm-atomic-load-store
- + changelog.d/fix-make-install-j
- + changelog.d/fix-use-std-ap-thunk
- + changelog.d/inter-module-far-jumps-aarch64-default
- compiler/GHC/ByteCode/Breakpoints.hs
- compiler/GHC/ByteCode/Types.hs
- compiler/GHC/Cmm/Expr.hs
- compiler/GHC/Cmm/Parser.y
- compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
- compiler/GHC/Core/Coercion/Opt.hs
- compiler/GHC/Driver/Config/StgToCmm.hs
- compiler/GHC/Driver/DynFlags.hs
- compiler/GHC/Driver/Flags.hs
- compiler/GHC/Driver/Main/Compile.hs
- compiler/GHC/Driver/Main/Hsc.hs
- compiler/GHC/Driver/Main/Passes.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Hs/Binds.hs
- compiler/GHC/Hs/Dump.hs
- compiler/GHC/Hs/Instances.hs
- compiler/GHC/Hs/Utils.hs
- compiler/GHC/HsToCore/Breakpoints.hs
- + compiler/GHC/HsToCore/Breakpoints/Types.hs
- compiler/GHC/HsToCore/Pmc/Desugar.hs
- compiler/GHC/HsToCore/Pmc/Solver.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/HsToCore/Ticks.hs
- compiler/GHC/Iface/Ext/Ast.hs
- compiler/GHC/Iface/Load.hs
- compiler/GHC/Iface/Make.hs
- compiler/GHC/Iface/Recomp.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/Annotation.hs
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Platform/Ways.hs
- compiler/GHC/Rename/Bind.hs
- compiler/GHC/Rename/Expr.hs
- compiler/GHC/Rename/Module.hs
- compiler/GHC/Rename/Names.hs
- compiler/GHC/Rename/Utils.hs
- compiler/GHC/Runtime/Eval.hs
- compiler/GHC/StgToCmm/Bind.hs
- compiler/GHC/StgToCmm/Config.hs
- compiler/GHC/Tc/Deriv.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/Head.hs
- compiler/GHC/Tc/Instance/Typeable.hs
- compiler/GHC/Tc/Types/Rank.hs
- compiler/GHC/ThToHs.hs
- compiler/GHC/Unit/Module/ModGuts.hs
- compiler/GHC/Unit/Module/ModIface.hs
- compiler/GHC/Unit/Module/WholeCoreBindings.hs
- compiler/GHC/Utils/Binary.hs
- compiler/Language/Haskell/Syntax/Binds.hs
- compiler/Language/Haskell/Syntax/Extension.hs
- compiler/ghc.cabal.in
- docs/users_guide/expected-undocumented-flags.txt
- docs/users_guide/exts/rank_polymorphism.rst
- docs/users_guide/exts/static_pointers.rst
- docs/users_guide/using-optimisation.rst
- ghc/GHCi/UI.hs
- hadrian/bindist/Makefile
- hadrian/cabal.project
- hadrian/src/Rules.hs
- hadrian/src/Rules/BinaryDist.hs
- libraries/base/changelog.md
- libraries/base/src/System/Environment.hs
- libraries/base/tests/T15349.stderr
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/src/GHC/Internal/Event/Control.hs
- libraries/ghc-internal/src/GHC/Internal/Event/Manager.hs
- libraries/ghc-internal/src/GHC/Internal/Event/TimerManager.hs
- libraries/ghc-internal/src/GHC/Internal/Exception/Type.hs
- libraries/ghc-internal/src/GHC/Internal/IO/Handle/Lock.hs
- libraries/ghc-internal/tests/backtraces/T14532b.stdout
- nofib
- rts/Capability.c
- rts/Capability.h
- rts/ContinuationOps.cmm
- rts/IOManager.c
- rts/IOManager.h
- rts/IOManagerInternals.h
- rts/PrimOps.cmm
- rts/RaiseAsync.c
- rts/RtsStartup.c
- rts/RtsSymbols.c
- rts/Schedule.c
- rts/Schedule.h
- rts/include/rts/IOInterface.h
- rts/include/rts/storage/Closures.h
- rts/include/rts/storage/TSO.h
- rts/posix/FdWakeup.h
- + rts/posix/MIO.c
- + rts/posix/MIO.h
- rts/posix/Poll.c
- rts/posix/Poll.h
- rts/posix/Select.c
- rts/posix/Select.h
- rts/posix/Signals.c
- rts/posix/Signals.h
- rts/posix/Timeout.c
- rts/posix/Timeout.h
- rts/rts.cabal
- rts/sm/NonMovingMark.c
- rts/win32/AsyncMIO.c
- rts/win32/AsyncMIO.h
- rts/win32/AsyncWinIO.h
- rts/win32/AwaitEvent.c
- rts/win32/AwaitEvent.h
- rts/win32/ConsoleHandler.h
- rts/win32/MIOManager.h
- rts/win32/ThrIOManager.h
- rts/win32/WorkQueue.h
- rts/win32/veh_excn.h
- testsuite/driver/junit.py
- testsuite/driver/perf_notes.py
- testsuite/driver/testglobals.py
- testsuite/driver/testlib.py
- testsuite/driver/testutil.py
- testsuite/tests/backpack/should_compile/T13149.bkp
- testsuite/tests/cmm/should_run/AtomicFetch.hs
- testsuite/tests/cmm/should_run/AtomicFetch_cmm.cmm
- + testsuite/tests/codeGen/should_run/T27430.hs
- + testsuite/tests/codeGen/should_run/T27430.stdout
- + testsuite/tests/codeGen/should_run/T27430_c.c
- testsuite/tests/codeGen/should_run/all.T
- testsuite/tests/codeGen/should_run/cgrun025.stderr
- + testsuite/tests/corelint/T27374.hs
- testsuite/tests/corelint/all.T
- testsuite/tests/count-deps/CountDepsParser.stdout
- testsuite/tests/determinism/determ017/A.hs
- testsuite/tests/exceptions/T26759.stderr
- testsuite/tests/ghc-api/T25121_status.stdout
- testsuite/tests/ghc-api/exactprint/T22919.stderr
- testsuite/tests/ghc-api/exactprint/Test20239.stderr
- testsuite/tests/ghc-api/exactprint/ZeroWidthSemi.stderr
- testsuite/tests/ghc-e/should_fail/T18441fail7.stderr
- testsuite/tests/ghci/scripts/T12005.script
- testsuite/tests/ghci/scripts/bytecodeIPE.hs
- testsuite/tests/ghci/should_run/Makefile
- + testsuite/tests/ghci/should_run/T27287.hs
- + testsuite/tests/ghci/should_run/T27287.stdout
- testsuite/tests/ghci/should_run/all.T
- testsuite/tests/haddock/perf/Fold.hs
- testsuite/tests/haddock/should_compile_flag_haddock/T17544.stderr
- testsuite/tests/haddock/should_compile_flag_haddock/T17544_kw.stderr
- testsuite/tests/haddock/should_compile_flag_haddock/T24221.stderr
- testsuite/tests/indexed-types/should_fail/T7354.hs
- testsuite/tests/interface-stability/base-exports.stdout
- testsuite/tests/interface-stability/base-exports.stdout-javascript-unknown-ghcjs
- testsuite/tests/interface-stability/base-exports.stdout-mingw32
- testsuite/tests/layout/layout001.stdout
- testsuite/tests/layout/layout002.stdout
- testsuite/tests/layout/layout003.stdout
- testsuite/tests/layout/layout004.stdout
- testsuite/tests/layout/layout005.stdout
- testsuite/tests/layout/layout006.stdout
- testsuite/tests/layout/layout007.stdout
- testsuite/tests/layout/layout008.stdout
- testsuite/tests/layout/layout009.stdout
- testsuite/tests/linear/should_compile/T1735Min.hs
- testsuite/tests/mdo/should_fail/mdofail006.stderr
- testsuite/tests/module/mod185.stderr
- testsuite/tests/parser/should_compile/DumpParsedAst.stderr
- testsuite/tests/parser/should_compile/DumpParsedAstComments.stderr
- testsuite/tests/parser/should_compile/DumpRenamedAst.stderr
- testsuite/tests/parser/should_compile/DumpSemis.stderr
- testsuite/tests/parser/should_compile/DumpTypecheckedAst.stderr
- testsuite/tests/parser/should_compile/KindSigs.stderr
- + testsuite/tests/parser/should_compile/T13087.stderr
- testsuite/tests/parser/should_compile/T14189.stderr
- testsuite/tests/parser/should_compile/T15323.stderr
- testsuite/tests/parser/should_compile/T20452.stderr
- testsuite/tests/parser/should_compile/T20718.stderr
- testsuite/tests/parser/should_compile/T20718b.stderr
- testsuite/tests/parser/should_compile/T20846.stderr
- testsuite/tests/parser/should_compile/T23315/T23315.stderr
- testsuite/tests/parser/should_fail/T8431.stderr
- testsuite/tests/parser/should_fail/readFail038.stderr
- testsuite/tests/perf/compiler/T3064.hs
- + testsuite/tests/pmcheck/should_compile/T27314.hs
- + testsuite/tests/pmcheck/should_compile/T27360.hs
- testsuite/tests/pmcheck/should_compile/all.T
- testsuite/tests/polykinds/T7594.hs
- testsuite/tests/printer/AnnotationNoListTuplePuns.stdout
- testsuite/tests/printer/T18791.stderr
- testsuite/tests/printer/Test20297.stdout
- testsuite/tests/printer/Test24533.stdout
- testsuite/tests/programs/thurston-modular-arith/Main.hs
- testsuite/tests/rts/ipe/IpeStats/Fold.hs
- testsuite/tests/runghc/T7859.stderr-mingw32
- testsuite/tests/simplCore/should_compile/T11562.hs
- testsuite/tests/simplCore/should_run/T3591.hs
- testsuite/tests/typecheck/should_compile/DeepSubsumption02.hs
- testsuite/tests/typecheck/should_compile/T12507.hs
- testsuite/tests/typecheck/should_compile/T13951.hs
- testsuite/tests/typecheck/should_compile/T15242.stderr
- testsuite/tests/typecheck/should_compile/T18920.hs
- testsuite/tests/typecheck/should_compile/T2595.hs
- testsuite/tests/typecheck/should_compile/T7541.hs
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_fail/T15067.stderr
- + testsuite/tests/typecheck/should_fail/T26532.hs
- + testsuite/tests/typecheck/should_fail/T26532.stderr
- testsuite/tests/typecheck/should_fail/T6069.stderr
- testsuite/tests/typecheck/should_fail/T7368a.hs
- testsuite/tests/typecheck/should_fail/T9858b.stderr
- testsuite/tests/typecheck/should_fail/TcStaticPointersFail02.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/typecheck/should_run/T1735_Help/Basics.hs
- testsuite/tests/typecheck/should_run/T3731-short.hs
- testsuite/tests/typecheck/should_run/T3731.hs
- testsuite/tests/typecheck/should_run/church.hs
- testsuite/tests/typecheck/should_run/tcrun008.hs
- testsuite/tests/typecheck/should_run/tcrun017.hs
- testsuite/tests/typecheck/should_run/tcrun026.hs
- testsuite/tests/typecheck/should_run/tcrun035.hs
- testsuite/tests/typecheck/should_run/tcrun036.hs
- utils/check-exact/ExactPrint.hs
- utils/check-exact/Main.hs
- utils/check-exact/Transform.hs
- utils/check-exact/Utils.hs
- utils/deriveConstants/Main.hs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/36f760980d3f44cefc2358cd099013…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/36f760980d3f44cefc2358cd099013…
You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
1
0
[Git][ghc/ghc][wip/dcoutts/issue-26717] 16 commits: Remove unused tso->block_info.wakeup member
by Duncan Coutts (@dcoutts) 21 Jul '26
by Duncan Coutts (@dcoutts) 21 Jul '26
21 Jul '26
Duncan Coutts pushed to branch wip/dcoutts/issue-26717 at Glasgow Haskell Compiler / GHC
Commits:
28d9b4db by Duncan Coutts at 2026-07-21T13:52:03+01:00
Remove unused tso->block_info.wakeup member
Presumably it was used once, but not now.
- - - - -
41689cd2 by Duncan Coutts at 2026-07-21T13:52:11+01:00
Document StgTSOBlockInfo to say what cases use what members
In principle, tso->why_blocked is the tag for the StgTSOBlockInfo union,
so we should be able to say for each union member the why_blocked cases
that use that member.
- - - - -
b54269a6 by Duncan Coutts at 2026-07-21T13:52:11+01:00
Add a tso->block_info.mvar member and use it
in preference to the generic block_info.closure union member, with
casts.
The plan is that when we know what case we're in (via tso->why_blocked)
then we can always access the correct union member, and so we will only
need to access block_info.closure for generic cases where we don't know
or don't care.
- - - - -
2b6e63f9 by Duncan Coutts at 2026-07-21T13:52:11+01:00
Add a tso->block_info.unused member and use it
in preference to the generic block_info.closure union member, with
casts.
The plan is that when we know what case we're in (via tso->why_blocked)
then we can always access the correct union member, and so we will only
need to access block_info.closure for generic cases where we don't know
or don't care.
- - - - -
c500e1a6 by Duncan Coutts at 2026-07-21T13:52:11+01:00
Avoid storing to tso->block_info.closure
In one case we can use a specific union member (.prev) instead. In
several cases the stores were in fact redundant because of subsequent
overwrites.
In scavengeTSO we replace setting tso->block_info.closure to a valid
closure, with an assertion that the block_info.unused is already set to
END_TSO_QUEUE which is a valid (static) closure.
- - - - -
0989884c by Duncan Coutts at 2026-07-21T13:52:11+01:00
Renumber the tso->why_blocked constants
We can do this now because we have separated the internal values from
the external ones used in the eventlog.
This lets us put them back into a deliberate order and consolodate some
gaps.
More importantly, it is a prepation for a slightly more sophisticated
encoding.
- - - - -
d2ff8432 by Duncan Coutts at 2026-07-21T13:52:11+01:00
Define constants for the existing stg_threadStatuszh return codes
The stg_threadStatuszh reuses the internal tso->why_blocked codes but
also extends them with a couple previously magic values. This is awkward
since we need to know what those magic values are so we don't
accidentally use those values to mean something else. By pulling a
definition up to where the why_blocked codes are defined we will be able
to avoid mistakenly assining those codes some meaning (or just changing
the BlockedThreadComplete, BlockedThreadKilled code if necessary).
- - - - -
40bc048c by Duncan Coutts at 2026-07-21T13:52:11+01:00
Extend the tso->why_blocked encoding to indicate block_info closures
We use some bit tricks to cheaply and generically test if a
tso->why_blocked tag implies that the corresponding tso->block_info will
contain a non-trivial valid closure (i.e. not just block_info.unused set
to END_TSO_QUEUE).
In particular we arrange for most why_blocked values to naturally have a
distinguishing bit, but for the BlockedOn{Read,Write,Delay} cases, they
can come in either non-closure or closure forms. We allow an additional
bit to distinguish these cases. The non-closure forms are only from
legacy I/O managers: select and win32-legacy. So this extra bit
mechanism will be able to be retired once the legacy I/O managers are
themselves retired.
This means in a few places we need to untag the why_blocked value before
inspecting it, but in most places we do not.
- - - - -
11bb96ec by Duncan Coutts at 2026-07-21T13:52:11+01:00
Use BlockInfoForceNonClosure in the select I/O manager
- - - - -
9b6e3db0 by Duncan Coutts at 2026-07-21T13:52:12+01:00
Use BlockInfoForceNonClosure in the win32-legacy I/O manager
for the BlockedOn{Read,Write} since these use the non-heap allocated
StgAsyncIOResult.
- - - - -
f309f939 by Duncan Coutts at 2026-07-21T13:52:12+01:00
Enforce the why_blocked and block_info rules in checkTSO
We now check the cases wher IsBlockInfoClosure should hold, the cases
that are supposed to use block_info.unused == END_TSO_QUEUE, and which
cases are allowed to use BlockInfoForceNonClosure.
This partially enforces the use of why_blocked as a tag for the
block_info union. We could be stricter and check for the correct
expected info table for the closure cases.
- - - - -
f33be455 by Duncan Coutts at 2026-07-21T13:52:12+01:00
Use IsBlockInfoClosure to simplify several tests
In GC and generic traversal we need to know if we should look at the
block_info.closure or not. Now we can do just that using a cheap bit
test on the why_blocked tag.
This fixes issue 26717, where the problem was that some GC modes did not
know when to look at block_info.closure, because the poll I/O manager
uses a closure for BlockedOn{Read,Write} while the select I/O manager
uses a non-closure. Now this information is in the why_blocked tag
itself.
- - - - -
894b8f61 by Duncan Coutts at 2026-07-21T13:52:12+01:00
Remove the now-unused scavengeTSOIOManager
The GC no longer has to delegate to the I/O manager, since it can use
IsBlockInfoClosure to decide things itself.
- - - - -
c51c04a1 by Duncan Coutts at 2026-07-21T13:52:12+01:00
Remove duplicate assertion
- - - - -
11ca05c0 by Duncan Coutts at 2026-07-21T13:52:12+01:00
Follow atomic access rules more consistently for tso->why_blocked
The rule is this:
store block_info *before* why_blocked
store why_blocked using store release
load why_blocked using load acquire
load block_info *after* why_blocked
This is a an atomic store release / load acquire pair and (if the reads
are in a separate thread to the writes, and the read receives the value
stored) then this guarantees a full "happens before" relationship of
these stores and loads.
In some cases, we do not need a full load acquire, because we don't read
the block_info at all and so do not need any ordering. In this case we
just need an atomic relaxed load.
This was being followed in most places, but not all. If there's good
reason in any case that we don't need atomic access, then we should
document that in a comment. In the absence of that I think it's easier
to follow the rule everywhere.
- - - - -
10dff2ef by Duncan Coutts at 2026-07-21T13:55:12+01:00
Add a changelog entry
- - - - -
24 changed files:
- + changelog.d/T26716
- libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingDisabled.hsc
- libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingEnabled.hsc
- libraries/ghc-internal/src/GHC/Internal/Conc/Sync.hs
- rts/IOManager.c
- rts/IOManager.h
- rts/Messages.c
- rts/PrimOps.cmm
- rts/RaiseAsync.c
- rts/RaiseAsync.h
- rts/STM.c
- rts/Schedule.c
- rts/Threads.c
- rts/TraverseHeap.c
- rts/include/rts/Constants.h
- rts/include/rts/storage/TSO.h
- rts/posix/Poll.c
- rts/posix/Select.c
- rts/posix/Timeout.c
- rts/sm/Compact.c
- rts/sm/NonMovingMark.c
- rts/sm/Sanity.c
- rts/sm/Scav.c
- rts/win32/AsyncMIO.c
Changes:
=====================================
changelog.d/T26716
=====================================
@@ -0,0 +1,15 @@
+section: rts
+synopsis: Fix design of TSO blocking info, fixing a use-after-free bug
+issues: #26716 #26717
+mrs: !15519
+description: {
+ Experimental work on ASAN support for GHC (MR !15168) revealed a
+ use-after-free bug when using the combination of the new poll I/O
+ manager with the compacting GC. The ultimate cause is that a TSO's
+ `block_info` (used by I/O managers and many other parts of the RTS)
+ is sometimes a GC pointer and sometimes not, but without a consistent
+ and easy-to-follow rule for when this is the case. The solution has
+ been to clean up and enforce that the TSO's `why_blocked` enumeration
+ is a proper tag for the `block_info`, and to use an encoding that
+ determines precisely when the `block_info` is a GC pointer or not.
+}
=====================================
libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingDisabled.hsc
=====================================
@@ -63,7 +63,7 @@ parseWhatNext w = case w of
_ -> WhatNextUnknownValue w
parseWhyBlocked :: Word16 -> WhyBlocked
-parseWhyBlocked w = case w of
+parseWhyBlocked w = case untagWhyBlocked w of
(#const NotBlocked) -> NotBlocked
(#const BlockedOnMVar) -> BlockedOnMVar
(#const BlockedOnMVarRead) -> BlockedOnMVarRead
@@ -78,6 +78,9 @@ parseWhyBlocked w = case w of
(#const BlockedOnMsgThrowTo) -> BlockedOnMsgThrowTo
(#const ThreadMigrating) -> ThreadMigrating
_ -> WhyBlockedUnknownValue w
+ where
+ -- See Constants.h encoding for why_blocked
+ untagWhyBlocked why = why .&. 0x0f
parseTsoFlags :: Word32 -> [TsoFlags]
parseTsoFlags w | isSet (#const TSO_LOCKED) w = TsoLocked : parseTsoFlags (unset (#const TSO_LOCKED) w)
=====================================
libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingEnabled.hsc
=====================================
@@ -63,7 +63,7 @@ parseWhatNext w = case w of
_ -> WhatNextUnknownValue w
parseWhyBlocked :: Word16 -> WhyBlocked
-parseWhyBlocked w = case w of
+parseWhyBlocked w = case untagWhyBlocked w of
(#const NotBlocked) -> NotBlocked
(#const BlockedOnMVar) -> BlockedOnMVar
(#const BlockedOnMVarRead) -> BlockedOnMVarRead
@@ -78,6 +78,9 @@ parseWhyBlocked w = case w of
(#const BlockedOnMsgThrowTo) -> BlockedOnMsgThrowTo
(#const ThreadMigrating) -> ThreadMigrating
_ -> WhyBlockedUnknownValue w
+ where
+ -- See Constants.h encoding for why_blocked
+ untagWhyBlocked why = why .&. 0x0f
parseTsoFlags :: Word32 -> [TsoFlags]
parseTsoFlags w | isSet (#const TSO_LOCKED) w = TsoLocked : parseTsoFlags (unset (#const TSO_LOCKED) w)
=====================================
libraries/ghc-internal/src/GHC/Internal/Conc/Sync.hs
=====================================
@@ -607,13 +607,16 @@ threadStatus (ThreadId t) = IO $ \s ->
-- NB. keep these in sync with rts/include/rts/Constants.h
mk_stat 0 = ThreadRunning
mk_stat 1 = ThreadBlocked BlockedOnMVar
- mk_stat 2 = ThreadBlocked BlockedOnBlackHole
- mk_stat 6 = ThreadBlocked BlockedOnSTM
+ mk_stat 2 = ThreadBlocked BlockedOnMVar -- BlockedOnMVarRead
+ mk_stat 3 = ThreadBlocked BlockedOnBlackHole
+ mk_stat 4 = ThreadBlocked BlockedOnException
+ -- 5,6,7: BlockedOn{Read,Write,Delay}
+ mk_stat 8 = ThreadBlocked BlockedOnSTM
+ mk_stat 9 = ThreadBlocked BlockedOnForeignCall
mk_stat 10 = ThreadBlocked BlockedOnForeignCall
- mk_stat 11 = ThreadBlocked BlockedOnForeignCall
- mk_stat 12 = ThreadBlocked BlockedOnException
- mk_stat 14 = ThreadBlocked BlockedOnMVar -- possibly: BlockedOnMVarRead
- -- NB. these are hardcoded in rts/PrimOps.cmm
+ -- 11: ThreadMigrating
+ -- 12: BlockedOnDoProc
+ -- 13,14,15: unused
mk_stat 16 = ThreadFinished
mk_stat 17 = ThreadDied
mk_stat _ = ThreadBlocked BlockedOnOther
=====================================
rts/IOManager.c
=====================================
@@ -589,41 +589,6 @@ void markCapabilityIOManager(evac_fn evac, void *user, CapIOManager *iomgr)
}
-void scavengeTSOIOManager(StgTSO *tso)
-{
- switch (iomgr_type) {
-
- /* case IO_MANAGER_SELECT:
- * BlockedOn{Read,Write} uses block_info.fd
- * BlockedOnDelay uses block_info.target
- * both of these are not GC pointers, so there is nothing to do.
- */
-
-#if defined(IOMGR_ENABLED_POLL)
- case IO_MANAGER_POLL:
- /* BlockedOn{Read,Write} uses block_info.aiop
- * BlockedOnDelay uses block_info.timeout
- * both of these are heap allocated, so we can do the same in all
- * cases, which is why we can use the generic block_info.closure.
- */
- evacuate(&tso->block_info.closure);
- break;
-#endif
-
- /* case IO_MANAGER_WIN32_LEGACY:
- * BlockedOn{Read,Write,DoProc} uses block_info.async_reqID
- * which is a plain integer, so nothing to scavenge.
- */
-
- default:
- /* All the other I/O managers do not use I/O-related why_blocked
- * reasons, so there are no cases to handle.
- */
- break;
- }
-}
-
-
/* Declared in rts/IOInterface.h. Used only by the MIO threaded I/O manager on
* Unix platforms.
*/
@@ -824,16 +789,17 @@ bool syncIOWaitReady(CapIOManager *iomgr,
#if defined(IOMGR_ENABLED_SELECT)
case IO_MANAGER_SELECT:
{
- StgWord why_blocked = rw == IORead ? BlockedOnRead : BlockedOnWrite;
+ StgThreadWhyBlocked why_blocked = (rw == IORead ? BlockedOnRead
+ : BlockedOnWrite)
+ | BlockInfoForceNonClosure;
tso->block_info.fd = fd;
- RELEASE_STORE(&tso->why_blocked, why_blocked);
appendToIOBlockedQueue(iomgr, tso);
+ RELEASE_STORE(&tso->why_blocked, why_blocked);
return true;
}
#endif
#if defined(IOMGR_ENABLED_POLL)
case IO_MANAGER_POLL:
- ASSERT(tso->why_blocked == NotBlocked);
return syncIOWaitReadyPoll(iomgr, tso, rw, fd);
#endif
default:
@@ -890,8 +856,8 @@ bool syncDelay(CapIOManager *iomgr, StgTSO *tso, HsInt us_delay)
{
LowResTime target = getDelayTarget(us_delay);
tso->block_info.target = target;
- RELEASE_STORE(&tso->why_blocked, BlockedOnDelay);
insertIntoSleepingQueue(iomgr, tso, target);
+ RELEASE_STORE(&tso->why_blocked, BlockedOnDelay | BlockInfoForceNonClosure);
return true;
}
#endif
@@ -911,8 +877,8 @@ bool syncDelay(CapIOManager *iomgr, StgTSO *tso, HsInt us_delay)
* simplifies matters, so set the status to OnDoProc and put the
* delayed thread on the blocked_queue.
*/
- RELEASE_STORE(&tso->why_blocked, BlockedOnDoProc);
appendToIOBlockedQueue(iomgr, tso);
+ RELEASE_STORE(&tso->why_blocked, BlockedOnDoProc);
return true;
}
#endif
@@ -928,6 +894,7 @@ void syncDelayCancel(CapIOManager *iomgr, StgTSO *tso)
switch (iomgr_type) {
#if defined(IOMGR_ENABLED_SELECT)
case IO_MANAGER_SELECT:
+ ASSERT(tso->why_blocked == (BlockedOnDelay | BlockInfoForceNonClosure));
removeThreadFromQueue(iomgr->cap, &iomgr->sleeping_queue, tso);
break;
#endif
=====================================
rts/IOManager.h
=====================================
@@ -311,11 +311,6 @@ void exitIOManager(bool wait_threads);
void markCapabilityIOManager(evac_fn evac, void *user, CapIOManager *iomgr);
-/* GC hook: scavenge I/O related tso->block_info. Used by scavengeTSO.
- */
-void scavengeTSOIOManager(StgTSO *tso);
-
-
/* Several code paths are almost identical between read and write paths. In
* such cases we use a shared code path with an enum to say which we're doing.
*/
=====================================
rts/Messages.c
=====================================
@@ -267,7 +267,8 @@ uint32_t messageBlackHole(Capability *cap, MessageBlackHole *msg)
// NB. we check to make sure that the owner is not the same as
// the current thread, since in that case it will not be on
// the run queue.
- if (owner->why_blocked == NotBlocked && owner->id != msg->tso->id) {
+ if (RELAXED_LOAD(&owner->why_blocked) == NotBlocked &&
+ owner->id != msg->tso->id) {
promoteInRunQueue(cap, owner);
}
@@ -328,7 +329,8 @@ uint32_t messageBlackHole(Capability *cap, MessageBlackHole *msg)
msg->tso->id, owner->id);
// See above, #3838
- if (owner->why_blocked == NotBlocked && owner->id != msg->tso->id) {
+ if (RELAXED_LOAD(&owner->why_blocked) == NotBlocked &&
+ owner->id != msg->tso->id) {
promoteInRunQueue(cap, owner);
}
=====================================
rts/PrimOps.cmm
=====================================
@@ -1145,12 +1145,12 @@ stg_threadStatuszh ( gcptr tso )
// contents of block_info too, then we'd have to do some synchronisation.
if (what_next == ThreadComplete) {
- ret = 16; // NB. magic, matches up with GHC.Conc.threadStatus
+ ret = BlockedThreadComplete; // NB. magic, matches up with GHC.Conc.threadStatus
} else {
if (what_next == ThreadKilled) {
- ret = 17;
+ ret = BlockedThreadKilled;
} else {
- ret = why_blocked;
+ ret = UntagWhyBlocked(why_blocked);
}
}
@@ -2319,7 +2319,8 @@ stg_asyncReadzh ( W_ fd, W_ is_sock, W_ len, W_ buf )
StgTSO_block_info(CurrentTSO) = reqID;
ASSERT(StgTSO_why_blocked(CurrentTSO) == NotBlocked::I32);
- %release StgTSO_why_blocked(CurrentTSO) = BlockedOnRead::I32;
+ %release StgTSO_why_blocked(CurrentTSO) = BlockedOnRead::I32
+ | BlockInfoForceNonClosure::I32;
ccall appendToIOBlockedQueue(Capability_iomgr(MyCapability()) "ptr",
CurrentTSO "ptr");
@@ -2339,7 +2340,8 @@ stg_asyncWritezh ( W_ fd, W_ is_sock, W_ len, W_ buf )
StgTSO_block_info(CurrentTSO) = reqID;
ASSERT(StgTSO_why_blocked(CurrentTSO) == NotBlocked::I32);
- %release StgTSO_why_blocked(CurrentTSO) = BlockedOnWrite::I32;
+ %release StgTSO_why_blocked(CurrentTSO) = BlockedOnWrite::I32
+ | BlockInfoForceNonClosure::I32;
ccall appendToIOBlockedQueue(Capability_iomgr(MyCapability()) "ptr",
CurrentTSO "ptr");
=====================================
rts/RaiseAsync.c
=====================================
@@ -233,7 +233,6 @@ throwTo (Capability *cap, // the Capability we hold
uint32_t
throwToMsg (Capability *cap, MessageThrowTo *msg)
{
- StgWord status;
StgTSO *target = ACQUIRE_LOAD(&msg->target);
Capability *target_cap;
@@ -268,9 +267,9 @@ check_target:
return THROWTO_BLOCKED;
}
- status = ACQUIRE_LOAD(&target->why_blocked);
+ StgThreadWhyBlocked why_blocked = ACQUIRE_LOAD(&target->why_blocked);
- switch (status) {
+ switch (UntagWhyBlocked(why_blocked)) {
case NotBlocked:
{
if ((target->flags & TSO_BLOCKEX) == 0) {
@@ -354,7 +353,7 @@ check_target:
StgMVar *mvar;
StgInfoTable *info USED_IF_THREADS;
- mvar = (StgMVar *)target->block_info.closure;
+ mvar = target->block_info.mvar;
// ASSUMPTION: tso->block_info must always point to a
// closure. In the threaded RTS it does.
@@ -370,9 +369,10 @@ check_target:
// we have the MVar, let's check whether the thread
// is still blocked on the same MVar.
- if ((target->why_blocked != BlockedOnMVar
- && target->why_blocked != BlockedOnMVarRead)
- || (StgMVar *)target->block_info.closure != mvar) {
+ StgThreadWhyBlocked why_blocked_still = ACQUIRE_LOAD(&target->why_blocked);
+ if (( why_blocked_still != BlockedOnMVar
+ && why_blocked_still != BlockedOnMVarRead)
+ || target->block_info.mvar != mvar) {
unlockClosure((StgClosure *)mvar, info);
goto retry;
}
@@ -490,7 +490,7 @@ check_target:
goto retry;
default:
- barf("throwTo: unrecognised why_blocked (%d)", target->why_blocked);
+ barf("throwTo: unrecognised why_blocked (%d)", why_blocked);
}
barf("throwTo");
}
@@ -625,7 +625,7 @@ awakenBlockedExceptionQueue (Capability *cap, StgTSO *tso)
static void
removeFromMVarBlockedQueue (StgTSO *tso)
{
- StgMVar *mvar = (StgMVar*)tso->block_info.closure;
+ StgMVar *mvar = tso->block_info.mvar;
StgMVarTSOQueue *q = (StgMVarTSOQueue*)tso->_link;
if (q == (StgMVarTSOQueue*)END_TSO_QUEUE) {
@@ -667,7 +667,7 @@ removeFromMVarBlockedQueue (StgTSO *tso)
static void
removeFromQueues(Capability *cap, StgTSO *tso)
{
- switch (tso->why_blocked) {
+ switch (UntagWhyBlocked(ACQUIRE_LOAD(&tso->why_blocked))) {
case NotBlocked:
case ThreadMigrating:
@@ -721,8 +721,8 @@ removeFromQueues(Capability *cap, StgTSO *tso)
}
done:
- RELAXED_STORE(&tso->why_blocked, NotBlocked);
appendToRunQueue(cap, tso);
+ RELEASE_STORE(&tso->why_blocked, NotBlocked);
}
/* -----------------------------------------------------------------------------
@@ -1105,9 +1105,9 @@ done:
IF_DEBUG(sanity, checkTSO(tso));
// wake it up
- if (tso->why_blocked != NotBlocked) {
- tso->why_blocked = NotBlocked;
+ if (RELAXED_LOAD(&tso->why_blocked) != NotBlocked) {
appendToRunQueue(cap,tso);
+ RELEASE_STORE(&tso->why_blocked, NotBlocked);
}
return tso;
=====================================
rts/RaiseAsync.h
=====================================
@@ -56,7 +56,7 @@ void awakenBlockedExceptionQueue (Capability *cap, StgTSO *tso);
INLINE_HEADER int
interruptible(StgTSO *t)
{
- switch (t->why_blocked) {
+ switch (UntagWhyBlocked(t->why_blocked)) {
case BlockedOnMVar:
case BlockedOnSTM:
case BlockedOnMVarRead:
=====================================
rts/STM.c
=====================================
@@ -264,7 +264,7 @@ static StgBool cond_lock_tvar(Capability *cap,
static void park_tso(StgTSO *tso) {
ASSERT(tso -> why_blocked == NotBlocked);
- tso -> block_info.closure = (StgClosure *) END_TSO_QUEUE;
+ tso->block_info.unused = END_TSO_QUEUE;
RELEASE_STORE(&tso -> why_blocked, BlockedOnSTM);
TRACE("park_tso on tso=%p", tso);
}
=====================================
rts/Schedule.c
=====================================
@@ -181,7 +181,7 @@ static void truncateRunQueue(Capability *cap);
static StgTSO *popRunQueue (Capability *cap);
static inline EventThreadStatus eventlogThreadStatus(StgThreadReturnCode ret_code);
-static inline EventThreadStatus eventlogThreadStatusBlocked(StgWord why_blocked);
+static inline EventThreadStatus eventlogThreadStatusBlocked(StgThreadWhyBlocked why_blocked);
/* ---------------------------------------------------------------------------
Main scheduling loop.
@@ -531,7 +531,7 @@ run_thread:
#endif
if (ret == ThreadBlocked) {
- uint16_t why_blocked = ACQUIRE_LOAD(&t->why_blocked);
+ StgThreadWhyBlocked why_blocked = ACQUIRE_LOAD(&t->why_blocked);
EventThreadStatus status = eventlogThreadStatusBlocked(why_blocked);
StgWord32 status_detail = 0;
if (why_blocked == BlockedOnBlackHole) {
@@ -1074,7 +1074,7 @@ schedulePostRunThread (Capability *cap, StgTSO *t)
//
// and a is never equal to b given a consistent view of memory.
//
- if (t -> trec != NO_TREC && t -> why_blocked == NotBlocked) {
+ if (t -> trec != NO_TREC && RELAXED_LOAD(&t->why_blocked) == NotBlocked) {
if (!stmValidateNestOfTransactions(cap, t -> trec, true)) {
debugTrace(DEBUG_sched | DEBUG_stm,
"trec %p found wasting its time", t);
@@ -2506,10 +2506,11 @@ suspendThread (StgRegTable *reg, bool interruptible)
threadPaused(cap,tso);
+ tso->block_info.unused = END_TSO_QUEUE;
if (interruptible) {
- tso->why_blocked = BlockedOnCCall_Interruptible;
+ RELEASE_STORE(&tso->why_blocked, BlockedOnCCall_Interruptible);
} else {
- tso->why_blocked = BlockedOnCCall;
+ RELEASE_STORE(&tso->why_blocked, BlockedOnCCall);
}
// Hand back capability
@@ -2567,16 +2568,25 @@ resumeThread (void *task_)
tso = incall->suspended_tso;
incall->suspended_tso = NULL;
incall->suspended_cap = NULL;
+
+ // we set why_blocked previously in suspendThread
+ ASSERT(tso->why_blocked == BlockedOnCCall ||
+ tso->why_blocked == BlockedOnCCall_Interruptible);
+
// we will modify tso->_link
IF_NONMOVING_WRITE_BARRIER_ENABLED {
updateRemembSetPushClosure(cap, (StgClosure *)tso->_link);
}
tso->_link = END_TSO_QUEUE;
+ // but no need to modify tso->block_info.prev as coincidentally
+ // it has the value we want already (since in suspendThread we set
+ // tso->block_info.unused to END_TSO_QUEUE for BlockedOnCCall).
+ ASSERT(tso->block_info.prev == END_TSO_QUEUE);
traceEventRunThread(cap, tso);
/* Reset blocking status */
- tso->why_blocked = NotBlocked;
+ RELEASE_STORE(&tso->why_blocked, NotBlocked);
if ((tso->flags & TSO_BLOCKEX) == 0) {
// avoid locking the TSO if we don't have to
@@ -2949,8 +2959,9 @@ deleteThread (StgTSO *tso)
// The TSO must be on the run queue of the Capability we own, or
// we must own all Capabilities.
- if (tso->why_blocked != BlockedOnCCall &&
- tso->why_blocked != BlockedOnCCall_Interruptible) {
+ StgThreadWhyBlocked why_blocked = RELAXED_LOAD(&tso->why_blocked);
+ if (why_blocked != BlockedOnCCall &&
+ why_blocked != BlockedOnCCall_Interruptible) {
throwToSingleThreaded(tso->cap,tso,NULL);
}
}
@@ -2961,10 +2972,12 @@ deleteThread_(StgTSO *tso)
{ // for forkProcess only:
// like deleteThread(), but we delete threads in foreign calls, too.
- if (tso->why_blocked == BlockedOnCCall ||
- tso->why_blocked == BlockedOnCCall_Interruptible) {
+ StgThreadWhyBlocked why_blocked = RELAXED_LOAD(&tso->why_blocked);
+ if (why_blocked == BlockedOnCCall ||
+ why_blocked == BlockedOnCCall_Interruptible) {
tso->what_next = ThreadKilled;
appendToRunQueue(tso->cap, tso);
+ RELEASE_STORE(&tso->why_blocked, NotBlocked);
} else {
deleteThread(tso);
}
@@ -3354,7 +3367,7 @@ resurrectThreads (StgTSO *threads)
// Wake up the thread on the Capability it was last on
cap = tso->cap;
- switch (tso->why_blocked) {
+ switch (UntagWhyBlocked(RELAXED_LOAD(&tso->why_blocked))) {
case BlockedOnMVar:
case BlockedOnMVarRead:
/* Called by GC - sched_mutex lock is currently held. */
@@ -3426,7 +3439,7 @@ static inline EventThreadStatus eventlogThreadStatus(StgThreadReturnCode ret_cod
return thread_stop_code[ret_code];
}
-static inline EventThreadStatus eventlogThreadStatusBlocked(StgWord why_blocked)
+static inline EventThreadStatus eventlogThreadStatusBlocked(StgThreadWhyBlocked why_blocked)
{
- return thread_blocked_code[why_blocked];
+ return thread_blocked_code[UntagWhyBlocked(why_blocked)];
}
=====================================
rts/Threads.c
=====================================
@@ -97,8 +97,8 @@ createThread(Capability *cap, W_ size)
// Always start with the compiled code evaluator
tso->what_next = ThreadRunGHC;
- tso->block_info.closure = (StgClosure *)END_TSO_QUEUE;
- tso->why_blocked = NotBlocked;
+ tso->block_info.prev = END_TSO_QUEUE;
+ tso->why_blocked = NotBlocked;
tso->blocked_exceptions = END_BLOCKED_EXCEPTIONS_QUEUE;
tso->bq = (StgBlockingQueue *)END_TSO_QUEUE;
tso->flags = 0;
@@ -291,13 +291,12 @@ tryWakeupThread (Capability *cap, StgTSO *tso)
}
#endif
- switch (ACQUIRE_LOAD(&tso->why_blocked))
+ switch (UntagWhyBlocked(ACQUIRE_LOAD(&tso->why_blocked)))
{
case BlockedOnMVar:
case BlockedOnMVarRead:
{
if (tso->_link == END_TSO_QUEUE) {
- tso->block_info.closure = (StgClosure*)END_TSO_QUEUE;
goto unblock;
} else {
return;
@@ -336,8 +335,8 @@ tryWakeupThread (Capability *cap, StgTSO *tso)
unblock:
// just run the thread now, if the BH is not really available,
// we'll block again.
- tso->why_blocked = NotBlocked;
appendToRunQueue(cap,tso);
+ RELEASE_STORE(&tso->why_blocked, NotBlocked);
// We used to set the context switch flag here, which would
// trigger a context switch a short time in the future (at the end
@@ -368,7 +367,8 @@ migrateThread (Capability *from, StgTSO *tso, Capability *to)
traceEventMigrateThread (from, tso, to->no);
// ThreadMigrating tells the target cap that it needs to be added to
// the run queue when it receives the MSG_TRY_WAKEUP.
- tso->why_blocked = ThreadMigrating;
+ tso->block_info.unused = END_TSO_QUEUE;
+ RELEASE_STORE(&tso->why_blocked, ThreadMigrating);
tso->cap = to;
tryWakeupThread(from, tso);
}
@@ -876,9 +876,9 @@ loop:
// save why_blocked here, because waking up the thread destroys
// this information
- StgWord why_blocked = ACQUIRE_LOAD(&tso->why_blocked);
+ StgThreadWhyBlocked why_blocked = ACQUIRE_LOAD(&tso->why_blocked);
ASSERT(why_blocked == BlockedOnMVarRead || why_blocked == BlockedOnMVar);
- ASSERT(tso->block_info.closure == (StgClosure*)mvar);
+ ASSERT(tso->block_info.mvar == mvar);
// actually perform the takeMVar
StgStack* stack = tso->stackobj;
@@ -949,7 +949,7 @@ end:
void
printThreadBlockage(StgTSO *tso)
{
- switch (ACQUIRE_LOAD(&tso->why_blocked)) {
+ switch (UntagWhyBlocked(ACQUIRE_LOAD(&tso->why_blocked))) {
#if defined(mingw32_HOST_OS)
case BlockedOnDoProc:
debugBelch("is blocked on proc (request: %" FMT_Word ")", tso->block_info.async_reqID);
@@ -968,10 +968,10 @@ printThreadBlockage(StgTSO *tso)
#endif
break;
case BlockedOnMVar:
- debugBelch("is blocked on an MVar @ %p", tso->block_info.closure);
+ debugBelch("is blocked on an MVar @ %p", tso->block_info.mvar);
break;
case BlockedOnMVarRead:
- debugBelch("is blocked on atomic MVar read @ %p", tso->block_info.closure);
+ debugBelch("is blocked on atomic MVar read @ %p", tso->block_info.mvar);
break;
break;
case BlockedOnBlackHole:
@@ -1046,7 +1046,7 @@ printAllThreads(void)
debugBelch("other threads:\n");
for (g = 0; g < RtsFlags.GcFlags.generations; g++) {
for (t = generations[g].threads; t != END_TSO_QUEUE; t = next) {
- if (t->why_blocked != NotBlocked) {
+ if (RELAXED_LOAD(&t->why_blocked) != NotBlocked) {
printThreadStatus(t);
}
next = t->global_link;
=====================================
rts/TraverseHeap.c
=====================================
@@ -1242,15 +1242,12 @@ inner_loop:
traversePushClosure(ts, (StgClosure *) tso->blocked_exceptions, c, sep, child_data);
traversePushClosure(ts, (StgClosure *) tso->bq, c, sep, child_data);
traversePushClosure(ts, (StgClosure *) tso->trec, c, sep, child_data);
- switch (ACQUIRE_LOAD(&tso->why_blocked)) {
- case BlockedOnMVar:
- case BlockedOnMVarRead:
- case BlockedOnBlackHole:
- case BlockedOnMsgThrowTo:
+
+ StgThreadWhyBlocked why_blocked = ACQUIRE_LOAD(&tso->why_blocked);
+ if (IsBlockInfoClosure(why_blocked) && why_blocked != NotBlocked) {
+ // The NotBlocked case uses block_info.prev as a TSO back link.
+ // Do not follow in that case or we'll get into a loop.
traversePushClosure(ts, tso->block_info.closure, c, sep, child_data);
- break;
- default:
- break;
}
goto loop;
}
=====================================
rts/include/rts/Constants.h
=====================================
@@ -248,33 +248,86 @@
/*
* Constants for the why_blocked field of a TSO
- * NB. keep these in sync with GHC/Conc/Sync.hs: threadStatus
+ *
+ * These say why the TSO is blocked, and also act as the tag for the
+ * block_info union. The comment for each tag below says which member
+ * of the block_info union is used.
+ *
+ * We also use the why_blocked to determine if the block_info contains
+ * a closure or not. There are three classes of tag:
+ * 1. why_blocked tags where block_info is always a closure;
+ * 2. why_blocked tags where block_info is never a closure;
+ * 3. why_blocked tags where block_info is sometimes a closure;
+ *
+ * We use the following encoding scheme for the three classes above:
+ * 1. the tag value has bits 3 and 4 unset (values 0..7);
+ * 2. the tag value has bit 3 set (values 8..15); and
+ * 3. the tag value has bit 4 set when it is not a closure and unset
+ * when it is a closure.
+ *
+ * This scheme makes it cheap and simple to check if the GC needs to
+ * look at the block_info.closure.
+ *
+ * The reason for the encoding using 2 marker bits rather than 1 is
+ * that it minimises the cases in the code that need to use or check
+ * the tag bits. The only tags in class 3 are BlockedOn{Read,Write
+ * Delay} which are used by in-RTS I/O managers, and the only ones that
+ * need to use block_info members that are not a closure are the legacy
+ * I/O managers select and win32-legacy. So when these I/O managers are
+ * removed then we can simplify the encoding.
*/
-#define NotBlocked 0
-#define BlockedOnMVar 1
-#define BlockedOnMVarRead 14 /* TODO: renumber me, see #9003 */
-#define BlockedOnBlackHole 2
-#define BlockedOnRead 3
-#define BlockedOnWrite 4
-#define BlockedOnDelay 5
-#define BlockedOnSTM 6
-
-/* Win32 only: */
-#define BlockedOnDoProc 7
-
-/* Only relevant for THREADED_RTS: */
-#define BlockedOnCCall 10
-#define BlockedOnCCall_Interruptible 11
- /* same as above but permit killing the worker thread */
-
-/* Involved in a message sent to tso->msg_cap */
-#define BlockedOnMsgThrowTo 12
+#define BlockInfoForceNonClosure 16
+#define UntagWhyBlocked(why) ((why) & 15)
+#define IsBlockInfoClosure(why) (((why) & 24) == 0)
+/*
+ * In the threaded RTS there is an invariant that the block_info union
+ * is always a valid GC closure. To ensure this, the tags that use
+ * block_info.unused, always set it to END_TSO_QUEUE. The non-closure
+ * why_blocked tags are only used by I/O managers on the non-threaded
+ * RTS. New in-RTS I/O managers use the AIOP and TimeoutQueue mechanism
+ * which are closures.
+ *
+ * Note: keep these in sync with GHC/Conc/Sync.hs: threadStatus
+ * Note: keep these in sync with Schedule.c: eventlogThreadStatusBlocked which
+ * converts the constants here to the ones used in the eventlog.
+ * Note: keep the encoding here in sync with parseWhyBlocked in ghc-heap
+ */
+#define NotBlocked 0 /* Uses block_info.prev */
+#define BlockedOnMVar 1 /* Uses block_info.mvar */
+#define BlockedOnMVarRead 2 /* Uses block_info.mvar */
+#define BlockedOnBlackHole 3 /* Uses block_info.bh */
+#define BlockedOnMsgThrowTo 4 /* Uses block_info.throwto */
+#define BlockedOnRead 5 /* Uses block_info.aiop
+ or with BlockInfoForceNonClosure
+ uses .fd or .async_reqID */
+#define BlockedOnWrite 6 /* Uses block_info.aiop
+ or with BlockInfoForceNonClosure
+ uses .fd or .async_reqID */
+#define BlockedOnDelay 7 /* Uses block_info.timeout
+ or with BlockInfoForceNonClosure
+ uses .target */
+
+#define BlockedOnSTM 8 /* Uses block_info.unused */
+#define BlockedOnCCall 9 /* Uses block_info.unused */
+#define BlockedOnCCall_Interruptible 10 /* Uses block_info.unused
+ * Same as BlockedOnCCall but permits
+ * killing the worker thread */
+#define ThreadMigrating 11 /* Uses block_info.unused */
+#define BlockedOnDoProc 12 /* Uses block_info.async_reqID */
+
+/* Reserved values, not values that why_blocked currently use. They
+ * are used in primop stg_threadStatuszh and must not overlap with
+ * other why_blocked status values. They could be changed, if the
+ * threadStatus in ghc-internal is updated too.
+ */
+#define BlockedThreadComplete 16
+#define BlockedThreadKilled 17
-/* The thread is not on any run queues, but can be woken up
- by tryWakeupThread() */
-#define ThreadMigrating 13
+/* Next available non-closure why_blocked tag numbers are: 13,14,15
+ * For more closure tag numbers, shift up all the non-closure ones
+ * and adjust the BlockInfoForceNonClosure tag and related macros.
+ * If we reach BlockInfoForceNonClosure then shift that up. */
-/* Next number is 15. */
/*
* These constants are returned to the scheduler by a thread that has
@@ -286,6 +339,7 @@
#define ThreadYielding 3
#define ThreadBlocked 4
#define ThreadFinished 5
+/* If this is ever extended, also adjust the eventlogStopStatus mapping */
/*
* Flags for the tso->flags field.
=====================================
rts/include/rts/storage/TSO.h
=====================================
@@ -30,6 +30,15 @@ typedef StgWord64 StgThreadID;
#define tsoLocked(tso) ((tso)->flags & TSO_LOCKED)
+/* Type for the tso->why_blocked field. See values in Constants.h.
+ *
+ * The StgThreadWhyBlocked type could be 8-bits, but for reasons
+ * unclear it is currently 32-bits. Previous comments here claimed
+ * that the smallest atomic type on AArch64 is 32-bits, but this is
+ * false.
+ */
+typedef StgWord32 StgThreadWhyBlocked;
+
/*
* Type returned after running a thread. Values of this type
* include HeapOverflow, StackOverflow etc. See Constants.h for the
@@ -37,22 +46,47 @@ typedef StgWord64 StgThreadID;
*/
typedef unsigned int StgThreadReturnCode;
-/* Reason for thread being blocked. See comment above struct StgTso_. */
+/* Additional information about how the thread is blocked.
+ * The tso->why_blocked is the tag for this union. */
typedef union {
+ /* Used for generic read, for cases where block_info is a closure.
+ * Never used for writes. Use .unused below instead. */
StgClosure *closure;
- StgTSO *prev; // a back-link when the TSO is on the run queue (NotBlocked)
+
+ /* For why_blocked cases where block_info is unused, this will be set to
+ * END_TSO_QUEUE, to maintain invariant that block_info.closure is valid */
+ StgTSO *unused;
+
+ /* case NotBlocked: A back-link when the TSO is on the run queue */
+ StgTSO *prev;
+
+ /* case BlockedOnMVar, BlockedOnMVarRead: the mvar the TSO is blocked on */
+ StgMVar *mvar;
+
+ /* case BlockedOnBlackHole */
struct MessageBlackHole_ *bh;
+
+ /* case BlockedOnMsgThrowTo */
struct MessageThrowTo_ *throwto;
- struct MessageWakeup_ *wakeup;
+
+ /* case BlockedOnRead, BlockedOnWrite: legacy select I/O manager */
StgInt fd; /* StgInt instead of int, so that it's the same size as the ptrs */
+
+ /* case BlockedOnRead, BlockedOnWrite: new I/O managers */
StgAsyncIOOp *aiop;
+
+ /* case BlockedOnDelay: new I/O managers */
StgTimeoutQueue *timeout;
+
#if defined(mingw32_HOST_OS)
- // Only used by the Legacy Win32 I/O manager: the async request id for the
- // operation.
+ /* case BlockedOnRead, BlockedOnWrite, BlockedOnDoProc:
+ * only used by the win32-legacy I/O manager.
+ * This is the async request id for the operation. */
StgWord async_reqID;
#endif
+
#if !defined(THREADED_RTS)
+ /* case BlockedOnDelay: used by the select I/O manager */
StgWord target;
// Only for the legacy select I/O manager: the target time for a thread
// blocked in threadDelay, in units of 1ms. This is a compromise: we don't
@@ -73,7 +107,21 @@ typedef union {
* have the reason in the why_blocked field of the TSO, and some
* further info (such as the closure the thread is blocked on, or the
* file descriptor if the thread is waiting on I/O) in the block_info
- * field.
+ * field. See Constants.h for the why_blocked values.
+ *
+ * The why_blocked field must be updated atomically. The protocol for
+ * updating block_info and why_blocked fields together is as follows:
+ *
+ * Writes:
+ * - first write block_info (normal non-atomic write)
+ * - then write why_blocked with an atomic *store release*
+ *
+ * Reads:
+ * - first read why_blocked with an atomic *load acquire*
+ * - then read block_info (normal non-atomic read)
+ *
+ * Read of only why_blocked without block_info:
+ * - read why_blocked with an atomic *relaxed load*
*/
typedef struct StgTSO_ {
@@ -123,11 +171,7 @@ typedef struct StgTSO_ {
StgWord16 what_next; // Values defined in Constants.h
StgWord32 flags; // Values defined in Constants.h
- /*
- * N.B. why_blocked only has a handful of values but must be atomically
- * updated; the smallest width which AArch64 supports for is 32-bits.
- */
- StgWord32 why_blocked; // Values defined in Constants.h
+ StgThreadWhyBlocked why_blocked; // Values defined in Constants.h
StgTSOBlockInfo block_info; // Barrier provided by why_blocked
StgThreadID id;
StgWord32 saved_errno;
=====================================
rts/posix/Poll.c
=====================================
@@ -183,8 +183,9 @@ bool syncIOWaitReadyPoll(CapIOManager *iomgr, StgTSO *tso,
aiop->notify.tso = tso;
aiop->notify_type = NotifyTSO;
aiop->live = &stg_ASYNCIO_LIVE0_closure;
- tso->why_blocked = rw == IORead ? BlockedOnRead : BlockedOnWrite;
tso->block_info.aiop = aiop;
+ RELEASE_STORE(&tso->why_blocked, rw == IORead ? BlockedOnRead
+ : BlockedOnWrite);
return asyncIOWaitReadyPoll(iomgr, aiop, rw, fd);
}
@@ -230,7 +231,6 @@ void syncIOCancelPoll(CapIOManager *iomgr, StgTSO *tso)
* We don't put the TSO back on the run queue or change the why_blocked
* status, as that is done by removeFromQueues (in the throwTo* functions).
*/
- tso->block_info.closure = (StgClosure *)END_TSO_QUEUE;
/* We are in the TSO case, where the aiop was only reachable from the TSO
* itself, and thus it is now no longer be reachable at all.
@@ -300,10 +300,9 @@ static void notifyIOCompletion(CapIOManager *iomgr, StgAsyncIOOp *aiop)
* cap because the tso was not on the run queue of any cap and
* so is not subject to thread migration.
*/
- StgTSO *tso = aiop->notify.tso;
- tso->why_blocked = NotBlocked;
- tso->_link = END_TSO_QUEUE;
+ StgTSO *tso = aiop->notify.tso;
pushOnRunQueue(iomgr->cap, tso);
+ RELEASE_STORE(&tso->why_blocked, NotBlocked);
}
/* For the TSO case, the aiop was only reachable from the TSO
* itself, and thus it is now no longer be reachable at all.
=====================================
rts/posix/Select.c
=====================================
@@ -138,11 +138,10 @@ static bool wakeUpSleepingThreads (CapIOManager *iomgr, LowResTime now)
break;
}
iomgr->sleeping_queue = tso->_link;
- RELAXED_STORE(&tso->why_blocked, NotBlocked);
- tso->_link = END_TSO_QUEUE;
IF_DEBUG(scheduler, debugBelch("Waking up sleeping thread %"
FMT_StgThreadID "\n", tso->id));
pushOnRunQueue(iomgr->cap,tso);
+ RELEASE_STORE(&tso->why_blocked, NotBlocked);
flag = true;
}
return flag;
@@ -311,7 +310,7 @@ awaitCompletedTimeoutsOrIOSelect(CapIOManager *iomgr, bool wait)
* So the (int) cast should be removed across the code base once
* GHC requires a version of FreeBSD that has that change in it.
*/
- switch (ACQUIRE_LOAD(&tso->why_blocked)) {
+ switch (UntagWhyBlocked(ACQUIRE_LOAD(&tso->why_blocked))) {
case BlockedOnRead:
{
int fd = tso->block_info.fd;
@@ -449,7 +448,7 @@ awaitCompletedTimeoutsOrIOSelect(CapIOManager *iomgr, bool wait)
int fd;
enum FdState fd_state = RTS_FD_IS_BLOCKING;
- switch (tso->why_blocked) {
+ switch (UntagWhyBlocked(ACQUIRE_LOAD(&tso->why_blocked))) {
case BlockedOnRead:
fd = tso->block_info.fd;
@@ -488,9 +487,8 @@ awaitCompletedTimeoutsOrIOSelect(CapIOManager *iomgr, bool wait)
IF_DEBUG(scheduler,
debugBelch("Waking up blocked thread %" FMT_StgThreadID "\n",
tso->id));
- tso->why_blocked = NotBlocked;
- tso->_link = END_TSO_QUEUE;
pushOnRunQueue(iomgr->cap,tso);
+ RELEASE_STORE(&tso->why_blocked, NotBlocked);
break;
case RTS_FD_IS_BLOCKING:
if (prev == NULL)
=====================================
rts/posix/Timeout.c
=====================================
@@ -48,8 +48,8 @@ bool syncDelayTimeout(CapIOManager *iomgr, StgTSO *tso, HsInt us_delay)
initElemTimeoutQueue(timeout, notify, NotifyTSO, iomgr->cap->r.rCCCS);
ASSERT(tso->why_blocked == NotBlocked);
- tso->why_blocked = BlockedOnDelay;
tso->block_info.timeout = timeout;
+ RELEASE_STORE(&tso->why_blocked, BlockedOnDelay);
insertTimeoutQueue(&iomgr->timeout_queue, timeout, target);
@@ -67,8 +67,6 @@ void syncDelayCancelTimeout(CapIOManager *iomgr, StgTSO *tso)
deleteTimeoutQueue(&iomgr->timeout_queue, timeout);
- tso->block_info.closure = (StgClosure *)END_TSO_QUEUE;
-
/* the timeout is no longer accessible from anywhere (except here) */
IF_NONMOVING_WRITE_BARRIER_ENABLED {
updateRemembSetPushClosure(iomgr->cap, (StgClosure *)timeout);
@@ -118,10 +116,9 @@ static void notifyTimeoutCompletion(CapIOManager *iomgr, StgTimeout *timeout)
switch (timeout->notify_type) {
case NotifyTSO:
{
- StgTSO *tso = timeout->notify.tso;
- tso->why_blocked = NotBlocked;
- tso->_link = END_TSO_QUEUE;
+ StgTSO *tso = timeout->notify.tso;
pushOnRunQueue(iomgr->cap, tso);
+ RELEASE_STORE(&tso->why_blocked, NotBlocked);
break;
}
case NotifyMVar:
=====================================
rts/sm/Compact.c
=====================================
@@ -468,16 +468,10 @@ thread_TSO (StgTSO *tso)
thread_(&tso->_link);
thread_(&tso->global_link);
- switch (ACQUIRE_LOAD(&tso->why_blocked)) {
- case BlockedOnMVar:
- case BlockedOnMVarRead:
- case BlockedOnBlackHole:
- case BlockedOnMsgThrowTo:
- case NotBlocked:
+ if (IsBlockInfoClosure(ACQUIRE_LOAD(&tso->why_blocked))) {
+ /* This also follows the block_info.prev back-link in
+ * the NotBlocked case, which may not be necessary. */
thread_(&tso->block_info.closure);
- break;
- default:
- break;
}
thread_(&tso->blocked_exceptions);
thread_(&tso->bq);
=====================================
rts/sm/NonMovingMark.c
=====================================
@@ -1055,16 +1055,10 @@ trace_tso (MarkQueue *queue, StgTSO *tso)
if (tso->label != NULL) {
markQueuePushClosure_(queue, (StgClosure *) tso->label);
}
- switch (ACQUIRE_LOAD(&tso->why_blocked)) {
- case BlockedOnMVar:
- case BlockedOnMVarRead:
- case BlockedOnBlackHole:
- case BlockedOnMsgThrowTo:
- case NotBlocked:
+ if (IsBlockInfoClosure(ACQUIRE_LOAD(&tso->why_blocked))) {
+ /* This also follows the block_info.prev back-link in
+ * the NotBlocked case, which may not be necessary. */
markQueuePushClosure_(queue, tso->block_info.closure);
- break;
- default:
- break;
}
}
=====================================
rts/sm/Sanity.c
=====================================
@@ -779,13 +779,45 @@ checkTSO(StgTSO *tso)
info == &stg_WHITEHOLE_info); // used to happen due to STM doing
// lockTSO(), might not happen now
- if ( tso->why_blocked == BlockedOnMVar
- || tso->why_blocked == BlockedOnMVarRead
- || tso->why_blocked == BlockedOnBlackHole
- || tso->why_blocked == BlockedOnMsgThrowTo
- || tso->why_blocked == NotBlocked
- ) {
+ StgThreadWhyBlocked why_blocked = ACQUIRE_LOAD(&tso->why_blocked);
+ switch (why_blocked) {
+ case NotBlocked:
+ case BlockedOnMVar:
+ case BlockedOnMVarRead:
+ case BlockedOnBlackHole:
+ case BlockedOnMsgThrowTo:
+ case BlockedOnRead:
+ case BlockedOnWrite:
+ case BlockedOnDelay:
+ //TODO: we could be more specific and check BlockedOnMVar has an MVar,
+ // BlockedOnBlackHole has a message, BlockedOnRead has an AIOP etc.
+ ASSERT(IsBlockInfoClosure(why_blocked));
ASSERT(LOOKS_LIKE_CLOSURE_PTR(tso->block_info.closure));
+ break;
+
+ case BlockedOnSTM:
+ case BlockedOnCCall:
+ case BlockedOnCCall_Interruptible:
+ case ThreadMigrating:
+ ASSERT(!IsBlockInfoClosure(why_blocked));
+ ASSERT(tso->block_info.unused == END_TSO_QUEUE);
+ break;
+
+#if !defined(THREADED_RTS)
+ // Only these three can use BlockInfoForceNonClosure
+ case BlockedOnRead | BlockInfoForceNonClosure:
+ case BlockedOnWrite | BlockInfoForceNonClosure:
+ case BlockedOnDelay | BlockInfoForceNonClosure:
+#if defined(mingw32_HOST_OS)
+ case BlockedOnDoProc:
+#endif
+ ASSERT(!IsBlockInfoClosure(why_blocked));
+ break;
+#endif
+
+ default:
+ barf("checkTSO: strange tso->why_blocked: %d for TSO %"
+ FMT_StgThreadID " (%p)", why_blocked, tso->id, tso);
}
ASSERT(LOOKS_LIKE_CLOSURE_PTR(tso->bq));
=====================================
rts/sm/Scav.c
=====================================
@@ -138,29 +138,16 @@ scavengeTSO (StgTSO *tso)
evacuate((StgClosure **)&tso->label);
}
- switch (ACQUIRE_LOAD(&tso->why_blocked)) {
- case BlockedOnMVar:
- case BlockedOnMVarRead:
- case BlockedOnBlackHole:
- case BlockedOnMsgThrowTo:
- case NotBlocked:
+ if (IsBlockInfoClosure(ACQUIRE_LOAD(&tso->why_blocked))) {
evacuate(&tso->block_info.closure);
- break;
- case BlockedOnRead:
- case BlockedOnWrite:
- case BlockedOnDelay:
- case BlockedOnDoProc:
- scavengeTSOIOManager(tso);
- break;
- default:
+ } else {
#if defined(THREADED_RTS)
// in the THREADED_RTS, block_info.closure must always point to a
// valid closure, because we assume this in throwTo(). In the
// non-threaded RTS it might be a FD (for
// BlockedOnRead/BlockedOnWrite) or a time value (BlockedOnDelay)
- tso->block_info.closure = (StgClosure *)END_TSO_QUEUE;
+ ASSERT(tso->block_info.unused == END_TSO_QUEUE);
#endif
- break;
}
tso->dirty = gct->failed_to_evac;
=====================================
rts/win32/AsyncMIO.c
=====================================
@@ -304,7 +304,7 @@ start:
for(tso = iomgr->blocked_queue_hd; tso != END_TSO_QUEUE;
tso = tso->_link) {
- switch(ACQUIRE_LOAD(&tso->why_blocked)) {
+ switch (UntagWhyBlocked(ACQUIRE_LOAD(&tso->why_blocked))) {
case BlockedOnRead:
case BlockedOnWrite:
case BlockedOnDoProc:
@@ -324,8 +324,6 @@ start:
}
// Terminates the run queue + this inner for-loop.
- tso->_link = END_TSO_QUEUE;
- tso->why_blocked = NotBlocked;
// For stg_block_async frames (read/write/doProc),
// write len and errCode directly to the stack.
// For stg_block_noregs frames (delay), nothing
@@ -335,14 +333,14 @@ start:
tso->stackobj->sp[2] = (W_)errCode;
}
pushOnRunQueue(&MainCapability, tso);
+ RELEASE_STORE(&tso->why_blocked, NotBlocked);
break;
}
break;
- default:
- if (tso->why_blocked != NotBlocked) {
- barf("awaitRequests: odd thread state");
- }
+ case NotBlocked:
break;
+ default:
+ barf("awaitRequests: odd thread state");
}
prev = tso;
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e233ebde3d58c18bad7a8ffc7f2011…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/e233ebde3d58c18bad7a8ffc7f2011…
You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
1
0
Zubin pushed new branch wip/27532 at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/27532
You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
1
0
[Git][ghc/ghc][wip/dcoutts/issue-26717] 2 commits: Fixup: Renumber the tso->why_blocked constants
by Duncan Coutts (@dcoutts) 21 Jul '26
by Duncan Coutts (@dcoutts) 21 Jul '26
21 Jul '26
Duncan Coutts pushed to branch wip/dcoutts/issue-26717 at Glasgow Haskell Compiler / GHC
Commits:
9490d849 by Duncan Coutts at 2026-07-21T13:32:27+01:00
Fixup: Renumber the tso->why_blocked constants
a function got renamed after the comment was written
- - - - -
e233ebde by Duncan Coutts at 2026-07-21T13:33:21+01:00
Fixup ghc-heap to follow new encoding of why_blocked codes
Spotted by Cheng Shao during code review.
TODO: squash into:
"Extend the tso->why_blocked encoding to indicate block_info closures"
- - - - -
3 changed files:
- libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingDisabled.hsc
- libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingEnabled.hsc
- rts/include/rts/Constants.h
Changes:
=====================================
libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingDisabled.hsc
=====================================
@@ -63,7 +63,7 @@ parseWhatNext w = case w of
_ -> WhatNextUnknownValue w
parseWhyBlocked :: Word16 -> WhyBlocked
-parseWhyBlocked w = case w of
+parseWhyBlocked w = case untagWhyBlocked w of
(#const NotBlocked) -> NotBlocked
(#const BlockedOnMVar) -> BlockedOnMVar
(#const BlockedOnMVarRead) -> BlockedOnMVarRead
@@ -78,6 +78,9 @@ parseWhyBlocked w = case w of
(#const BlockedOnMsgThrowTo) -> BlockedOnMsgThrowTo
(#const ThreadMigrating) -> ThreadMigrating
_ -> WhyBlockedUnknownValue w
+ where
+ -- See Constants.h encoding for why_blocked
+ untagWhyBlocked why = why .&. 0x0f
parseTsoFlags :: Word32 -> [TsoFlags]
parseTsoFlags w | isSet (#const TSO_LOCKED) w = TsoLocked : parseTsoFlags (unset (#const TSO_LOCKED) w)
=====================================
libraries/ghc-heap/GHC/Exts/Heap/FFIClosures_ProfilingEnabled.hsc
=====================================
@@ -63,7 +63,7 @@ parseWhatNext w = case w of
_ -> WhatNextUnknownValue w
parseWhyBlocked :: Word16 -> WhyBlocked
-parseWhyBlocked w = case w of
+parseWhyBlocked w = case untagWhyBlocked w of
(#const NotBlocked) -> NotBlocked
(#const BlockedOnMVar) -> BlockedOnMVar
(#const BlockedOnMVarRead) -> BlockedOnMVarRead
@@ -78,6 +78,9 @@ parseWhyBlocked w = case w of
(#const BlockedOnMsgThrowTo) -> BlockedOnMsgThrowTo
(#const ThreadMigrating) -> ThreadMigrating
_ -> WhyBlockedUnknownValue w
+ where
+ -- See Constants.h encoding for why_blocked
+ untagWhyBlocked why = why .&. 0x0f
parseTsoFlags :: Word32 -> [TsoFlags]
parseTsoFlags w | isSet (#const TSO_LOCKED) w = TsoLocked : parseTsoFlags (unset (#const TSO_LOCKED) w)
=====================================
rts/include/rts/Constants.h
=====================================
@@ -288,8 +288,9 @@
* which are closures.
*
* Note: keep these in sync with GHC/Conc/Sync.hs: threadStatus
- * Note: keep these in sync with Schedule.c: eventlogStopStatus which
+ * Note: keep these in sync with Schedule.c: eventlogThreadStatusBlocked which
* converts the constants here to the ones used in the eventlog.
+ * Note: keep the encoding here in sync with parseWhyBlocked in ghc-heap
*/
#define NotBlocked 0 /* Uses block_info.prev */
#define BlockedOnMVar 1 /* Uses block_info.mvar */
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/40dc6744d655b9c82d32384f493288…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/40dc6744d655b9c82d32384f493288…
You're receiving this email because of your account on gitlab.haskell.org. Manage all notifications: https://gitlab.haskell.org/-/profile/notifications | Help: https://gitlab.haskell.org/help
1
0