30 Sep '25
Cheng Shao pushed new branch wip/perf-max-if-compression at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/perf-max-if-compression
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] autoconf/ghc-toolchain: remove obsolete C99 check
by Marge Bot (@marge-bot) 30 Sep '25
by Marge Bot (@marge-bot) 30 Sep '25
30 Sep '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
b8307eab by Cheng Shao at 2025-09-30T18:43:14-04:00
autoconf/ghc-toolchain: remove obsolete C99 check
This patch removes obsolete c99 check from autoconf/ghc-toolchain. For
all toolchain & platform combination we support, gnu11 or above is
already supported without any -std flag required, and our RTS already
required C11 quite a few years ago, so the C99 check is completely
pointless.
- - - - -
6 changed files:
- configure.ac
- distrib/configure.ac.in
- m4/fp_cmm_cpp_cmd_with_args.m4
- − m4/fp_set_cflags_c99.m4
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cc.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cpp.hs
Changes:
=====================================
configure.ac
=====================================
@@ -448,11 +448,6 @@ AC_SUBST([CmmCPPCmd])
AC_SUBST([CmmCPPArgs])
AC_SUBST([CmmCPPSupportsG0])
-FP_SET_CFLAGS_C99([CC],[CFLAGS],[CPPFLAGS])
-FP_SET_CFLAGS_C99([CC_STAGE0],[CONF_CC_OPTS_STAGE0],[CONF_CPP_OPTS_STAGE0])
-FP_SET_CFLAGS_C99([CC],[CONF_CC_OPTS_STAGE1],[CONF_CPP_OPTS_STAGE1])
-FP_SET_CFLAGS_C99([CC],[CONF_CC_OPTS_STAGE2],[CONF_CPP_OPTS_STAGE2])
-
dnl ** Do we have a compatible emsdk version?
dnl --------------------------------------------------------------
EMSDK_VERSION("3.1.20", "", "")
=====================================
distrib/configure.ac.in
=====================================
@@ -163,11 +163,6 @@ AC_SUBST([CmmCPPCmd])
AC_SUBST([CmmCPPArgs])
AC_SUBST([CmmCPPSupportsG0])
-FP_SET_CFLAGS_C99([CC],[CFLAGS],[CPPFLAGS])
-dnl FP_SET_CFLAGS_C99([CC_STAGE0],[CONF_CC_OPTS_STAGE0],[CONF_CPP_OPTS_STAGE0])
-FP_SET_CFLAGS_C99([CC],[CONF_CC_OPTS_STAGE1],[CONF_CPP_OPTS_STAGE1])
-FP_SET_CFLAGS_C99([CC],[CONF_CC_OPTS_STAGE2],[CONF_CPP_OPTS_STAGE2])
-
dnl ** Which ld to use?
dnl --------------------------------------------------------------
FIND_LD([$target],[GccUseLdOpt])
=====================================
m4/fp_cmm_cpp_cmd_with_args.m4
=====================================
@@ -56,27 +56,6 @@ else
AC_MSG_RESULT([no])
fi
-AC_MSG_CHECKING([the C-- preprocessor for C99 support])
-cat > conftest.c <<EOF
-#include <stdio.h>
-#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
-# error "Compiler does not advertise C99 conformance"
-#endif
-EOF
-if "$CMM_CPP_CMD" $CMM_CPP_ARGS conftest.c -o conftest -g0 >/dev/null 2>&1; then
- AC_MSG_RESULT([yes])
-else
- # Try -std=gnu99
- if "$CMM_CPP_CMD" -std=gnu99 $CMM_CPP_ARGS conftest.c -o conftest -g0 >/dev/null 2>&1; then
- $3="-std=gnu99 $$3"
- AC_MSG_RESULT([needs -std=gnu99])
- else
- AC_MSG_ERROR([C99-compatible compiler needed])
- fi
-fi
-rm -f conftest.c conftest.o conftest
-
-
$2="$CMM_CPP_CMD"
$3="$$3 $CMM_CPP_ARGS"
@@ -85,4 +64,3 @@ unset CMM_CPP_CMD
unset CMM_CPP_ARGS
])
-
=====================================
m4/fp_set_cflags_c99.m4 deleted
=====================================
@@ -1,38 +0,0 @@
-# FP_SET_CFLAGS_C99
-# ----------------------------------
-# figure out which CFLAGS are needed to place the compiler into C99 mode
-# $1 is name of CC variable (unmodified)
-# $2 is name of CC flags variable (augmented if needed)
-# $3 is name of CPP flags variable (augmented if needed)
-AC_DEFUN([FP_SET_CFLAGS_C99],
-[
- dnl save current state of AC_PROG_CC_C99
- FP_COPY_SHELLVAR([CC],[fp_save_CC])
- FP_COPY_SHELLVAR([CFLAGS],[fp_save_CFLAGS])
- FP_COPY_SHELLVAR([CPPFLAGS],[fp_save_CPPFLAGS])
- FP_COPY_SHELLVAR([ac_cv_prog_cc_c99],[fp_save_cc_c99])
- dnl set local state
- CC="$$1"
- CFLAGS="$$2"
- CPPFLAGS="$$3"
- unset ac_cv_prog_cc_c99
- dnl perform detection
- AC_PROG_CC_C99
- fp_cc_c99="$ac_cv_prog_cc_c99"
- case "x$ac_cv_prog_cc_c99" in
- x) ;; # noop
- xno) AC_MSG_ERROR([C99-compatible compiler needed]) ;;
- *) $2="$$2 $ac_cv_prog_cc_c99"
- $3="$$3 $ac_cv_prog_cc_c99"
- ;;
- esac
- dnl restore saved state
- FP_COPY_SHELLVAR([fp_save_CC],[CC])
- FP_COPY_SHELLVAR([fp_save_CFLAGS],[CFLAGS])
- FP_COPY_SHELLVAR([fp_save_CPPFLAGS],[CPPFLAGS])
- FP_COPY_SHELLVAR([fp_save_cc_c99],[ac_cv_prog_cc_c99])
- dnl cleanup
- unset fp_save_CC
- unset fp_save_CFLAGS
- unset fp_save_cc_c99
-])
=====================================
utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cc.hs
=====================================
@@ -11,7 +11,6 @@ module GHC.Toolchain.Tools.Cc
, compileC
, compileAsm
, addPlatformDepCcFlags
- , checkC99Support
) where
import Control.Monad
@@ -51,12 +50,8 @@ findCc archOs llvmTarget progOpt = do
cc1 <- ignoreUnusedArgs cc0
cc2 <- ccSupportsTarget archOs llvmTarget cc1
checking "whether Cc works" $ checkCcWorks cc2
- cc3 <- oneOf "cc doesn't support C99" $ map checkC99Support
- [ cc2
- , cc2 & _ccFlags %++ "-std=gnu99"
- ]
- checkCcSupportsExtraViaCFlags cc3
- return cc3
+ checkCcSupportsExtraViaCFlags cc2
+ return cc2
checkCcWorks :: Cc -> M ()
checkCcWorks cc = withTempDir $ \dir -> do
@@ -88,17 +83,6 @@ ccSupportsTarget archOs target cc =
checking "whether Cc supports --target" $
supportsTarget archOs _ccProgram checkCcWorks target cc
-checkC99Support :: Cc -> M Cc
-checkC99Support cc = checking "for C99 support" $ withTempDir $ \dir -> do
- let test_o = dir </> "test.o"
- compileC cc test_o $ unlines
- [ "#include <stdio.h>"
- , "#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L"
- , "# error \"Compiler does not advertise C99 conformance\""
- , "#endif"
- ]
- return cc
-
checkCcSupportsExtraViaCFlags :: Cc -> M ()
checkCcSupportsExtraViaCFlags cc = checking "whether cc supports extra via-c flags" $ withTempDir $ \dir -> do
let test_o = dir </> "test.o"
=====================================
utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cpp.hs
=====================================
@@ -19,7 +19,7 @@ import GHC.Toolchain.Prelude
import GHC.Toolchain.Program
import GHC.Toolchain.Tools.Cc
-import GHC.Toolchain.Utils (withTempDir, oneOf, expectFileExists)
+import GHC.Toolchain.Utils (withTempDir, expectFileExists)
newtype Cpp = Cpp { cppProgram :: Program
}
@@ -160,13 +160,7 @@ findJsCpp progOpt cc = checking "for JavaScript C preprocessor" $ do
findCmmCpp :: ProgOpt -> Cc -> M CmmCpp
findCmmCpp progOpt cc = checking "for a Cmm preprocessor" $ do
-- Use the specified CPP or try to use the c compiler
- foundCppProg <- findProgram "Cmm preprocessor" progOpt [] <|> pure (programFromOpt progOpt (prgPath $ ccProgram cc) [])
- -- Check whether the C preprocessor needs -std=gnu99 (only very old toolchains need this)
- Cc cpp <- oneOf "cc doesn't support C99" $ map checkC99Support
- [ Cc foundCppProg
- , Cc (foundCppProg & _prgFlags %++ "-std=gnu99")
- ]
-
+ cpp <- findProgram "Cmm preprocessor" progOpt [] <|> pure (programFromOpt progOpt (prgPath $ ccProgram cc) [])
cmmCppSupportsG0 <- withTempDir $ \dir -> do
let conftest = dir </> "conftest.c"
writeFile conftest "int main(void) {}"
@@ -181,14 +175,9 @@ findCmmCpp progOpt cc = checking "for a Cmm preprocessor" $ do
findCpp :: ProgOpt -> Cc -> M Cpp
findCpp progOpt cc = checking "for C preprocessor" $ do
-- Use the specified CPP or try to use the c compiler
- foundCppProg <- findProgram "C preprocessor" progOpt [] <|> pure (programFromOpt progOpt (prgPath $ ccProgram cc) [])
- -- Check whether the C preprocessor needs -std=gnu99 (only very old toolchains need this)
- Cc cpp2 <- oneOf "cc doesn't support C99" $ map checkC99Support
- [ Cc foundCppProg
- , Cc (foundCppProg & _prgFlags %++ "-std=gnu99")
- ]
+ cpp <- findProgram "C preprocessor" progOpt [] <|> pure (programFromOpt progOpt (prgPath $ ccProgram cc) [])
-- Always add the -E flag to the CPP, regardless of the user options
- let cppProgram = addFlagIfNew "-E" cpp2
+ let cppProgram = addFlagIfNew "-E" cpp
return Cpp{cppProgram}
--------------------------------------------------------------------------------
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b8307eab80c5809df5405d76c822bf8…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/b8307eab80c5809df5405d76c822bf8…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] driver: Load bytecode static pointer entries during linking
by Marge Bot (@marge-bot) 30 Sep '25
by Marge Bot (@marge-bot) 30 Sep '25
30 Sep '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
e9445c01 by Matthew Pickering at 2025-09-30T18:42:23-04:00
driver: Load bytecode static pointer entries during linking
Previously the entries were loaded too eagerly, during upsweep, but we
should delay loading them until we know that the relevant bytecode
object is demanded.
Towards #25230
- - - - -
4 changed files:
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Iface/Tidy/StaticPtrTable.hs
- compiler/GHC/Linker/Loader.hs
Changes:
=====================================
compiler/GHC/Driver/Main.hs
=====================================
@@ -102,7 +102,6 @@ module GHC.Driver.Main
, dumpIfaceStats
, ioMsgMaybe
, showModuleIndex
- , hscAddSptEntries
, writeInterfaceOnlyMode
, loadByteCode
, genModDetails
@@ -2515,9 +2514,6 @@ hscParsedDecls hsc_env decls = runInteractiveHsc hsc_env $ do
let src_span = srcLocSpan interactiveSrcLoc
_ <- liftIO $ loadDecls interp hsc_env src_span linkable
- {- Load static pointer table entries -}
- liftIO $ hscAddSptEntries hsc_env (cg_spt_entries tidy_cg)
-
let tcs = filterOut isImplicitTyCon (mg_tcs simpl_mg)
patsyns = mg_patsyns simpl_mg
@@ -2539,18 +2535,6 @@ hscParsedDecls hsc_env decls = runInteractiveHsc hsc_env $ do
fam_insts defaults fix_env
return (new_tythings, new_ictxt)
--- | Load the given static-pointer table entries into the interpreter.
--- See Note [Grand plan for static forms] in "GHC.Iface.Tidy.StaticPtrTable".
-hscAddSptEntries :: HscEnv -> [SptEntry] -> IO ()
-hscAddSptEntries hsc_env entries = do
- let interp = hscInterp hsc_env
- let add_spt_entry :: SptEntry -> IO ()
- add_spt_entry (SptEntry n fpr) = do
- -- These are only names from the current module
- (val, _, _) <- loadName interp hsc_env n
- addSptEntry interp fpr val
- mapM_ add_spt_entry entries
-
{-
Note [Fixity declarations in GHCi]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=====================================
compiler/GHC/Driver/Make.hs
=====================================
@@ -56,8 +56,6 @@ import GHC.Tc.Utils.Monad ( initIfaceCheck, concatMapM )
import GHC.Runtime.Interpreter
import qualified GHC.Linker.Loader as Linker
-import GHC.Linker.Types
-
import GHC.Driver.Config.Diagnostic
import GHC.Driver.Pipeline
@@ -72,8 +70,6 @@ import GHC.Driver.MakeSem
import GHC.Driver.Downsweep
import GHC.Driver.MakeAction
-import GHC.ByteCode.Types
-
import GHC.Iface.Load ( cannotFindModule, readIface )
import GHC.IfaceToCore ( typecheckIface )
import GHC.Iface.Recomp ( RecompileRequired(..), CompileReason(..) )
@@ -1232,31 +1228,9 @@ upsweep_mod :: HscEnv
upsweep_mod hsc_env mHscMessage old_hmi summary mod_index nmods = do
hmi <- compileOne' mHscMessage hsc_env summary
mod_index nmods (hm_iface <$> old_hmi) (maybe emptyHomeModInfoLinkable hm_linkable old_hmi)
-
- -- MP: This is a bit janky, because before you add the entries you have to extend the HPT with the module
- -- you just compiled. Another option, would be delay adding anything until after upsweep has finished, but I
- -- am unsure if this is sound (wrt running TH splices for example).
- -- This function only does anything if the linkable produced is a BCO, which
- -- used to only happen with the bytecode backend, but with
- -- @-fprefer-byte-code@, @HomeModInfo@ has bytecode even when generating
- -- object code, see #25230.
hscInsertHPT hmi hsc_env
- addSptEntries (hsc_env)
- (homeModInfoByteCode hmi)
-
return hmi
--- | Add the entries from a BCO linkable to the SPT table, see
--- See Note [Grand plan for static forms] in GHC.Iface.Tidy.StaticPtrTable.
-addSptEntries :: HscEnv -> Maybe Linkable -> IO ()
-addSptEntries hsc_env mlinkable =
- hscAddSptEntries hsc_env
- [ spt
- | linkable <- maybeToList mlinkable
- , bco <- linkableBCOs linkable
- , spt <- bc_spt_entries bco
- ]
-
-- Note [When source is considered modified]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=====================================
compiler/GHC/Iface/Tidy/StaticPtrTable.hs
=====================================
@@ -124,7 +124,7 @@ Here is a running example:
* If we are compiling for the byte-code interpreter, we instead explicitly add
the SPT entries (recorded in CgGuts' cg_spt_entries field) to the interpreter
process' SPT table using the addSptEntry interpreter message. This happens
- in upsweep after we have compiled the module (see GHC.Driver.Make.upsweep').
+ when the bytecode object is linked in `dynLinkBCOs`.
-}
import GHC.Prelude
=====================================
compiler/GHC/Linker/Loader.hs
=====================================
@@ -718,6 +718,7 @@ loadDecls interp hsc_env span linkable = do
let ce2 = extendClosureEnv (closure_env le2) nms_fhvs
!pls2 = pls { linker_env = le2 { closure_env = ce2 }
, linked_breaks = lb2 }
+ mapM_ (linkSptEntry interp ce2) (concatMap bc_spt_entries cbcs)
return (pls2, (nms_fhvs, links_needed, units_needed))
where
cbcs = linkableBCOs linkable
@@ -951,10 +952,28 @@ dynLinkBCOs interp pls bcos = do
-- Wrap finalizers on the ones we want to keep
new_binds <- makeForeignNamedHValueRefs interp to_add
+
let ce2 = extendClosureEnv (closure_env le2) new_binds
+
+ -- Add SPT entries
+ mapM_ (linkSptEntry interp ce2) (concatMap bc_spt_entries cbcs)
+
return $! pls1 { linker_env = le2 { closure_env = ce2 }
, linked_breaks = lb2 }
+-- | Register SPT entries for this module in the interpreter
+-- Assumes that the name from the SPT has already been loaded into the interpreter.
+linkSptEntry :: Interp -> ClosureEnv -> SptEntry -> IO ()
+linkSptEntry interp ce (SptEntry name fpr) = do
+ case lookupNameEnv ce name of
+ -- The SPT entries only point to locally defined names, which should have already been
+ -- loaded into the interpreter before this function is called.
+ Nothing -> pprPanic "linkSptEntry" (ppr name)
+ Just (_, hval) -> addSptEntry interp fpr hval
+
+
+
+
-- Link a bunch of BCOs and return references to their values
linkSomeBCOs :: Interp
-> PkgsLoaded
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e9445c013fbccf9318739ca3d095a3e…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/e9445c013fbccf9318739ca3d095a3e…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] 3 commits: ghci: fix lookupSymbolInDLL behavior on wasm
by Marge Bot (@marge-bot) 30 Sep '25
by Marge Bot (@marge-bot) 30 Sep '25
30 Sep '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
02a7c18a by Cheng Shao at 2025-09-30T18:41:27-04:00
ghci: fix lookupSymbolInDLL behavior on wasm
This patch fixes lookupSymbolInDLL behavior on wasm to return Nothing
instead of throwing. On wasm, we only have lookupSymbol, and the
driver would attempt to call lookupSymbolInDLL first before falling
back to lookupSymbol, so lookupSymbolInDLL needs to return Nothing
gracefully for the fallback behavior to work.
- - - - -
aa0ca5e3 by Cheng Shao at 2025-09-30T18:41:27-04:00
hadrian/compiler: enable internal-interpreter for ghc library in wasm stage1
This commit enables the internal-interpreter flag for ghc library in
wasm stage1, as well as other minor adjustments to make it actually
possible to launch a ghc api session that makes use of the internal
interpreter. Closes #26431 #25400.
- - - - -
69503668 by Cheng Shao at 2025-09-30T18:41:27-04:00
testsuite: add T26431 test case
This commit adds T26431 to testsuite/tests/ghci-wasm which goes
through the complete bytecode compilation/linking/running pipeline in
wasm, so to witness that the ghc shared library in wasm have full
support for internal-interpreter.
- - - - -
9 changed files:
- compiler/GHC.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Runtime/Interpreter/Types.hs
- hadrian/src/Settings/Packages.hs
- libraries/ghci/GHCi/ObjLink.hs
- + testsuite/tests/ghci-wasm/T26431.hs
- + testsuite/tests/ghci-wasm/T26431.stdout
- testsuite/tests/ghci-wasm/all.T
Changes:
=====================================
compiler/GHC.hs
=====================================
@@ -716,17 +716,14 @@ setTopSessionDynFlags dflags = do
-- see Note [Target code interpreter]
interp <- if
+#if !defined(wasm32_HOST_ARCH)
-- Wasm dynamic linker
| ArchWasm32 <- platformArch $ targetPlatform dflags
-> do
s <- liftIO $ newMVar InterpPending
loader <- liftIO Loader.uninitializedLoader
dyld <- liftIO $ makeAbsolute $ topDir dflags </> "dyld.mjs"
-#if defined(wasm32_HOST_ARCH)
- let libdir = sorry "cannot spawn child process on wasm"
-#else
libdir <- liftIO $ last <$> Loader.getGccSearchDirectory logger dflags "libraries"
-#endif
let profiled = ways dflags `hasWay` WayProf
way_tag = if profiled then "_p" else ""
let cfg =
@@ -747,6 +744,7 @@ setTopSessionDynFlags dflags = do
wasmInterpUnitState = ue_homeUnitState $ hsc_unit_env hsc_env
}
pure $ Just $ Interp (ExternalInterp $ ExtWasm $ ExtInterpState cfg s) loader lookup_cache
+#endif
-- JavaScript interpreter
| ArchJavaScript <- platformArch (targetPlatform dflags)
=====================================
compiler/GHC/Driver/Session.hs
=====================================
@@ -3763,12 +3763,17 @@ makeDynFlagsConsistent dflags
-- only supports dynamic code
| LinkInMemory <- ghcLink dflags
, sTargetRTSLinkerOnlySupportsSharedLibs $ settings dflags
+#if defined(HAVE_INTERNAL_INTERPRETER)
+ , not (ways dflags `hasWay` WayDyn)
+#else
, not (ways dflags `hasWay` WayDyn && gopt Opt_ExternalInterpreter dflags)
+#endif
= flip loopNoWarn "Forcing dynamic way because target RTS linker only supports dynamic code" $
- -- See checkOptions, -fexternal-interpreter is
- -- required when using --interactive with a non-standard
- -- way (-prof, -static, or -dynamic).
+#if !defined(HAVE_INTERNAL_INTERPRETER)
+ -- Force -fexternal-interpreter if internal-interpreter is not
+ -- available at this stage
setGeneralFlag' Opt_ExternalInterpreter $
+#endif
addWay' WayDyn dflags
| LinkInMemory <- ghcLink dflags
=====================================
compiler/GHC/Linker/Loader.hs
=====================================
@@ -1614,6 +1614,9 @@ gccSearchDirCache = unsafePerformIO $ newIORef []
-- which dominate a large percentage of startup time on Windows.
getGccSearchDirectory :: Logger -> DynFlags -> String -> IO [FilePath]
getGccSearchDirectory logger dflags key = do
+#if defined(wasm32_HOST_ARCH)
+ pure []
+#else
cache <- readIORef gccSearchDirCache
case lookup key cache of
Just x -> return x
@@ -1640,6 +1643,7 @@ getGccSearchDirectory logger dflags key = do
x:_ -> case break (=='=') x of
(_ , []) -> []
(_, (_:xs)) -> xs
+#endif
-- | Get a list of system search directories, this to alleviate pressure on
-- the findSysDll function.
=====================================
compiler/GHC/Runtime/Interpreter/Types.hs
=====================================
@@ -214,7 +214,7 @@ data JSInterpConfig = JSInterpConfig
data WasmInterpConfig = WasmInterpConfig
{ wasmInterpDyLD :: !FilePath -- ^ Location of dyld.mjs script
- , wasmInterpLibDir :: FilePath -- ^ wasi-sdk sysroot libdir containing libc.so, etc
+ , wasmInterpLibDir :: !FilePath -- ^ wasi-sdk sysroot libdir containing libc.so, etc
, wasmInterpOpts :: ![String] -- ^ Additional command line arguments for iserv
-- wasm ghci browser mode
=====================================
hadrian/src/Settings/Packages.hs
=====================================
@@ -82,15 +82,18 @@ packageArgs = do
]
, builder (Cabal Flags) ? mconcat
- -- For the ghc library, internal-interpreter only makes
- -- sense when we're not cross compiling. For cross GHC,
- -- external interpreter is used for loading target code
- -- and internal interpreter is supposed to load native
- -- code for plugins (!7377), however it's unfinished work
- -- (#14335) and completely untested in CI for cross
- -- backends at the moment, so we might as well disable it
- -- for cross GHC.
- [ andM [expr (ghcWithInterpreter stage), notCross] `cabalFlag` "internal-interpreter"
+ -- In order to enable internal-interpreter for the ghc
+ -- library:
+ --
+ -- 1. ghcWithInterpreter must be True ("Use interpreter" =
+ -- "YES")
+ -- 2. For non-cross case it can be enabled
+ -- 3. For cross case, disable for stage0 since that runs
+ -- on the host and must rely on external interpreter to
+ -- load target code, otherwise enable for stage1 since
+ -- that runs on the target and can use target's own
+ -- ghci object linker
+ [ andM [expr (ghcWithInterpreter stage), orM [notCross, stage1]] `cabalFlag` "internal-interpreter"
, orM [ notM cross, haveCurses ] `cabalFlag` "terminfo"
, arg "-build-tool-depends"
, flag UseLibzstd `cabalFlag` "with-libzstd"
=====================================
libraries/ghci/GHCi/ObjLink.hs
=====================================
@@ -113,8 +113,7 @@ foreign import javascript unsafe "__ghc_wasm_jsffi_dyld.lookupSymbol($1)"
js_lookupSymbol :: JSString -> IO (Ptr a)
lookupSymbolInDLL :: Ptr LoadedDLL -> String -> IO (Maybe (Ptr a))
-lookupSymbolInDLL _ sym =
- throwIO $ ErrorCall $ "lookupSymbolInDLL: unsupported on wasm for " <> sym
+lookupSymbolInDLL _ _ = pure Nothing
resolveObjs :: IO Bool
resolveObjs = pure True
=====================================
testsuite/tests/ghci-wasm/T26431.hs
=====================================
@@ -0,0 +1,35 @@
+import Control.Exception
+import Control.Monad.IO.Class
+import Data.Maybe
+import GHC
+import GHC.Plugins
+import GHC.Runtime.Interpreter
+import System.Environment.Blank
+
+main :: IO ()
+main = do
+ [libdir] <- getArgs
+ defaultErrorHandler defaultFatalMessager defaultFlushOut $
+ runGhc (Just libdir) $
+ do
+ dflags0 <- getSessionDynFlags
+ let dflags1 =
+ dflags0
+ { ghcMode = CompManager,
+ backend = interpreterBackend,
+ ghcLink = LinkInMemory
+ }
+ logger <- getLogger
+ (dflags2, _, _) <-
+ parseDynamicFlags logger dflags1 $
+ map noLoc ["-package", "ghc"]
+ _ <- setSessionDynFlags dflags2
+ addTarget =<< guessTarget "hello.hs" Nothing Nothing
+ _ <- load LoadAllTargets
+ setContext
+ [ IIDecl $ simpleImportDecl $ mkModuleName "Prelude",
+ IIDecl $ simpleImportDecl $ mkModuleName "Main"
+ ]
+ hsc_env <- getSession
+ fhv <- compileExprRemote "main"
+ liftIO $ evalIO (fromJust $ hsc_interp hsc_env) fhv
=====================================
testsuite/tests/ghci-wasm/T26431.stdout
=====================================
@@ -0,0 +1 @@
+main = putStrLn "hello world"
=====================================
testsuite/tests/ghci-wasm/all.T
=====================================
@@ -10,3 +10,11 @@ test('T26430', [
extra_hc_opts('-L. -lT26430B')]
, compile_and_run, ['']
)
+
+test('T26431', [
+ extra_files(['../../../.gitlab/hello.hs']),
+ extra_hc_opts('-package ghc'),
+ extra_run_opts(f'"{config.libdir}"'),
+ ignore_stderr]
+, compile_and_run, ['']
+)
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b7e21e498d39e0ee764e3237544b4c…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/b7e21e498d39e0ee764e3237544b4c…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][master] 2 commits: rts: Fix lost wakeups in threadPaused for threads blocked on black holes
by Marge Bot (@marge-bot) 30 Sep '25
by Marge Bot (@marge-bot) 30 Sep '25
30 Sep '25
Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
a1de535f by Luite Stegeman at 2025-09-30T18:40:28-04:00
rts: Fix lost wakeups in threadPaused for threads blocked on black holes
The lazy blackholing code in threadPaused could overwrite closures
that were already eagerly blackholed, and as such wouldn't have a
marked update frame. If the black hole was overwritten by its
original owner, this would lead to an undetected collision, and
the contents of any existing blocking queue being lost.
This adds a check for eagerly blackholed closures and avoids
overwriting their contents.
Fixes #26324
- - - - -
b7e21e49 by Luite Stegeman at 2025-09-30T18:40:28-04:00
rts: push the correct update frame in stg_AP_STACK
The frame contains an eager black hole (__stg_EAGER_BLACKHOLE_info) so
we should push an stg_bh_upd_frame_info instead of an stg_upd_frame_info.
- - - - -
3 changed files:
- compiler/GHC/Cmm/Parser.y
- rts/Apply.cmm
- rts/ThreadPaused.c
Changes:
=====================================
compiler/GHC/Cmm/Parser.y
=====================================
@@ -1321,6 +1321,7 @@ stmtMacros = listToUFM [
( fsLit "PROF_HEADER_CREATE", \[e] -> profHeaderCreate e ),
( fsLit "PUSH_UPD_FRAME", \[sp,e] -> emitPushUpdateFrame sp e ),
+ ( fsLit "PUSH_BH_UPD_FRAME", \[sp,e] -> emitPushBHUpdateFrame sp e ),
( fsLit "SET_HDR", \[ptr,info,ccs] ->
emitSetDynHdr ptr info ccs ),
( fsLit "TICK_ALLOC_PRIM", \[hdr,goods,slop] ->
@@ -1336,6 +1337,10 @@ emitPushUpdateFrame :: CmmExpr -> CmmExpr -> FCode ()
emitPushUpdateFrame sp e = do
emitUpdateFrame sp mkUpdInfoLabel e
+emitPushBHUpdateFrame :: CmmExpr -> CmmExpr -> FCode ()
+emitPushBHUpdateFrame sp e = do
+ emitUpdateFrame sp mkBHUpdInfoLabel e
+
pushStackFrame :: [CmmParse CmmExpr] -> CmmParse () -> CmmParse ()
pushStackFrame fields body = do
profile <- getProfile
=====================================
rts/Apply.cmm
=====================================
@@ -699,7 +699,7 @@ INFO_TABLE(stg_AP_STACK,/*special layout*/0,0,AP_STACK,"AP_STACK","AP_STACK")
/* ensure there is at least AP_STACK_SPLIM words of headroom available
* after unpacking the AP_STACK. See bug #1466 */
- PUSH_UPD_FRAME(Sp - SIZEOF_StgUpdateFrame, R1);
+ PUSH_BH_UPD_FRAME(Sp - SIZEOF_StgUpdateFrame, R1);
Sp = Sp - SIZEOF_StgUpdateFrame - WDS(Words);
TICK_ENT_AP();
=====================================
rts/ThreadPaused.c
=====================================
@@ -15,6 +15,7 @@
#include "RaiseAsync.h"
#include "Trace.h"
#include "Threads.h"
+#include "Messages.h"
#include "sm/NonMovingMark.h"
#include <string.h> // for memmove()
@@ -314,52 +315,66 @@ threadPaused(Capability *cap, StgTSO *tso)
continue;
}
- // an EAGER_BLACKHOLE or CAF_BLACKHOLE gets turned into a
- // BLACKHOLE here.
+ // If we have a frame that is already eagerly blackholed, we
+ // shouldn't overwrite its payload: There may already be a blocking
+ // queue (see #26324).
+ if(frame_info == &stg_bh_upd_frame_info) {
+ // eager black hole: we do nothing
+
+ // it should be a black hole that we own
+ ASSERT(bh_info == &stg_BLACKHOLE_info ||
+ bh_info == &__stg_EAGER_BLACKHOLE_info ||
+ bh_info == &stg_CAF_BLACKHOLE_info);
+ ASSERT(blackHoleOwner(bh) == tso || blackHoleOwner(bh) == NULL);
+ } else {
+ // lazy black hole
+
#if defined(THREADED_RTS)
- // first we turn it into a WHITEHOLE to claim it, and if
- // successful we write our TSO and then the BLACKHOLE info pointer.
- cur_bh_info = (const StgInfoTable *)
- cas((StgVolatilePtr)&bh->header.info,
- (StgWord)bh_info,
- (StgWord)&stg_WHITEHOLE_info);
-
- if (cur_bh_info != bh_info) {
- bh_info = cur_bh_info;
+ // first we turn it into a WHITEHOLE to claim it, and if
+ // successful we write our TSO and then the BLACKHOLE info pointer.
+ cur_bh_info = (const StgInfoTable *)
+ cas((StgVolatilePtr)&bh->header.info,
+ (StgWord)bh_info,
+ (StgWord)&stg_WHITEHOLE_info);
+
+ if (cur_bh_info != bh_info) {
+ bh_info = cur_bh_info;
#if defined(PROF_SPIN)
- NONATOMIC_ADD(&whitehole_threadPaused_spin, 1);
+ NONATOMIC_ADD(&whitehole_threadPaused_spin, 1);
#endif
- busy_wait_nop();
- goto retry;
- }
+ busy_wait_nop();
+ goto retry;
+ }
#endif
-
- IF_NONMOVING_WRITE_BARRIER_ENABLED {
- if (ip_THUNK(INFO_PTR_TO_STRUCT(bh_info))) {
- // We are about to replace a thunk with a blackhole.
- // Add the free variables of the closure we are about to
- // overwrite to the update remembered set.
- // N.B. We caught the WHITEHOLE case above.
- updateRemembSetPushThunkEager(cap,
- THUNK_INFO_PTR_TO_STRUCT(bh_info),
- (StgThunk *) bh);
+ ASSERT(bh_info != &stg_WHITEHOLE_info);
+
+ IF_NONMOVING_WRITE_BARRIER_ENABLED {
+ if (ip_THUNK(INFO_PTR_TO_STRUCT(bh_info))) {
+ // We are about to replace a thunk with a blackhole.
+ // Add the free variables of the closure we are about to
+ // overwrite to the update remembered set.
+ // N.B. We caught the WHITEHOLE case above.
+ updateRemembSetPushThunkEager(cap,
+ THUNK_INFO_PTR_TO_STRUCT(bh_info),
+ (StgThunk *) bh);
+ }
}
- }
- // zero out the slop so that the sanity checker can tell
- // where the next closure is. N.B. We mustn't do this until we have
- // pushed the free variables to the update remembered set above.
- OVERWRITING_CLOSURE_SIZE(bh, closure_sizeW_(bh, INFO_PTR_TO_STRUCT(bh_info)));
+ // zero out the slop so that the sanity checker can tell
+ // where the next closure is. N.B. We mustn't do this until we have
+ // pushed the free variables to the update remembered set above.
+ OVERWRITING_CLOSURE_SIZE(bh, closure_sizeW_(bh, INFO_PTR_TO_STRUCT(bh_info)));
- // The payload of the BLACKHOLE points to the TSO
- RELEASE_STORE(&((StgInd *)bh)->indirectee, (StgClosure *)tso);
- SET_INFO_RELEASE(bh,&stg_BLACKHOLE_info);
+ // The payload of the BLACKHOLE points to the TSO
+ RELEASE_STORE(&((StgInd *)bh)->indirectee, (StgClosure *)tso);
+ SET_INFO_RELEASE(bh,&stg_BLACKHOLE_info);
- // .. and we need a write barrier, since we just mutated the closure:
- recordClosureMutated(cap,bh);
+ // .. and we need a write barrier, since we just mutated the closure:
+ recordClosureMutated(cap,bh);
- // We pretend that bh has just been created.
- LDV_RECORD_CREATE(bh);
+ // We pretend that bh has just been created.
+ LDV_RECORD_CREATE(bh);
+ }
frame = (StgClosure *) ((StgUpdateFrame *)frame + 1);
if (prev_was_update_frame) {
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9c304ec00750b69acb854cd47e50bd…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/9c304ec00750b69acb854cd47e50bd…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T23162-spj] 42 commits: Revert "Add necessary flag for js linking"
by Simon Peyton Jones (@simonpj) 30 Sep '25
by Simon Peyton Jones (@simonpj) 30 Sep '25
30 Sep '25
Simon Peyton Jones pushed to branch wip/T23162-spj at Glasgow Haskell Compiler / GHC
Commits:
c1cab0c3 by Sylvain Henry at 2025-09-26T10:36:30-04:00
Revert "Add necessary flag for js linking"
This reverts commit 84f68e2231b2eddb2e1dc4e90af394ef0f2e803f.
This commit didn't have the expected effect. See discussion in #26290.
Instead we export HEAP8 and HEAPU8 from rts/js/mem.js
- - - - -
0a434a80 by Sylvain Henry at 2025-09-26T10:36:30-04:00
JS: export HEAPU8 (#26290)
This is now required by newer Emscripten versions.
- - - - -
b10296a9 by Andreas Klebinger at 2025-09-26T10:37:11-04:00
sizeExpr: Improve Tick handling.
When determining if we scrutinize a function argument we
now properly look through ticks. Fixes #26444.
- - - - -
d9e2a9a7 by mniip at 2025-09-26T16:00:50-04:00
rts: Refactor parsing of -h flags
We have a nontrivial amount of heap profiling flags available in the
non-profiled runtime, so it makes sense to reuse the parsing code
between the profiled and the non-profiled runtime, only restricting
which flags are allowed.
- - - - -
089e45aa by mniip at 2025-09-26T16:00:50-04:00
rts: Fix parsing of -h options with braces
When the "filter by" -h options were introduced in
bc210f7d267e8351ccb66972f4b3a650eb9338bb, the braces were mandatory.
Then in 3c22fb21fb18e27ce8d941069a6915fce584a526, the braces were made
optional. Then in d1ce35d2271ac8b79cb5e37677b1a989749e611c the brace
syntax stopped working, and no one seems to have noticed.
- - - - -
423f1472 by mniip at 2025-09-26T16:00:50-04:00
rts: add -hT<type> and -hi<table id> heap filtering options (#26361)
They are available in non-profiled builds.
Along the way fixed a bug where combining -he<era> and -hr<retainer>
would ignore whether the retainer matches or not.
- - - - -
4cda4785 by mniip at 2025-09-26T16:00:50-04:00
docs: Document -hT<type> and -hi<addr>
- - - - -
982ad30f by mniip at 2025-09-26T16:00:50-04:00
rts: Refactor dumping the heap census
Always do the printing of the total size right next to where the bucket
label is printed. This prevents accidentally printing a label without
the corresponding amount.
Fixed a bug where exactly this happened for -hi profile and the 0x0
(uncategorized) info table.
There is now also much more symmetry between fprintf(hp_file,...) and
the corresponding traceHeapProfSampleString.
- - - - -
8cbe006a by Cheng Shao at 2025-09-26T16:01:34-04:00
hadrian: fix GHC.Platform.Host generation for cross stage1
This patch fixes incorrectly GHC.Platform.Host generation logic for
cross stage1 in hadrian (#26449). Also adds T26449 test case to
witness the fix.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
0ddd0fdc by soulomoon at 2025-09-28T19:24:10-04:00
Remove hptAllInstances usage during upsweep
Previously, during the upsweep phase when
checking safe imports, we were loading the module
interface with runTcInteractive, which in turn calls
hptAllInstances. This accesses non-below modules
from the home package table.
Change the implementation of checkSafeImports
to use initTcWithGbl and loadSysInterface to load the
module interface, since we already have TcGblEnv at hand.
This eliminates the unnecessary use of runTcInteractive
and hptAllInstances during the upsweep phase.
- - - - -
e05c496c by Ben Gamari at 2025-09-28T19:24:59-04:00
base: Update changelog to reflect timing of IOPort# removal
This change will make 9.14 afterall.
- - - - -
bdc9d130 by Cheng Shao at 2025-09-28T19:25:45-04:00
rts: fix wasm JSFFI initialization constructor code
This commit fixes wasm JSFFI initialization constructor code so that
the constructor is self-contained and avoids invoking a fake
__main_argc_argv function. The previous approach of reusing
__main_void logic in wasi-libc saves a tiny bit of code, at the
expense of link-time trouble whenever GHC links a wasm module without
-no-hs-main, in which case the driver-generated main function would
clash with the definition here, resulting in a linker error. It's
simply better to avoid messing with the main function, and it would
additionally allow linking wasm32-wasi command modules that does make
use of synchronous JSFFI.
- - - - -
5d59fc8f by Cheng Shao at 2025-09-28T19:26:27-04:00
rts: provide stub implementations of ExecPage functions for wasm
This patch provides stub implementations of ExecPage functions for
wasm. They are never actually invoked at runtime for any non-TNTC
platform, yet they can cause link-time errors of missing symbols when
the GHCi.InfoTable module gets linked into the final wasm module (e.g.
a GHC API program).
- - - - -
a4d664c7 by Cheng Shao at 2025-09-29T17:29:22+02:00
compiler/ghci: replace the LoadDLL message with LoadDLLs
As a part of #25407, this commit changes the LoadDLL message to
LoadDLLs, which takes a list of DLL paths to load and returns the list
of remote pointer handles. The wasm dyld is refactored to take
advantage of LoadDLLs and harvest background parallelism. On other
platforms, LoadDLLs is based on a fallback codepath that does
sequential loading.
The driver is not actually emitting singular LoadDLLs message with
multiple DLLs yet, this is left in subsequent commits.
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
c7fc4bae by Cheng Shao at 2025-09-29T17:29:22+02:00
driver: separate downsweep/upsweep phase in loadPackages'
This commit refactors GHC.Linker.Loader.loadPackages' to be separated
into downsweep/upsweep phases:
- The downsweep phase performs dependency analysis and generates a
list of topologically sorted packages to load
- The upsweep phase sequentially loads these packages by calling
loadPackage
This is a necessary refactoring to make it possible to make loading of
DLLs concurrent.
- - - - -
ab180104 by Cheng Shao at 2025-09-29T17:57:19+02:00
driver: emit single LoadDLLs message to load multiple DLLs
This commit refactors the driver so that it emits a single LoadDLLs
message to load multiple DLLs in GHC.Linker.Loader.loadPackages'.
Closes #25407.
-------------------------
Metric Increase:
MultiLayerModulesTH_OneShot
TcPlugin_RewritePerf
-------------------------
Co-authored-by: Codex <codex(a)openai.com>
- - - - -
9c304ec0 by Sean D. Gillespie at 2025-09-29T19:57:07-04:00
Fix SIZED_BIN_OP_TY_INT casts in RTS interpreter
Correct `SIZED_BIN_OP_TY_INT` cast to integer. Previously, it cast
its second operand as its parameter `ty`. This does not currently
cause any issues, since we are only using it for bit shifts.
Fixes #26287
- - - - -
aa700203 by Richard Eisenberg at 2025-09-30T23:20:04+01:00
Move some fundep solving to new spot
Work in progress...[skip ci]
This completes moving dict fundeps to the main loop
We need wanted/wanted fundeps too
...and some other refactors
Wibbles
Make FunDeps into a new module
Solve new_eqs rather than adding them to WantedConstraints
Wibble
Import wibbles
Comments only [skip ci]
WIP on FunDeps [skip ci]
Work in progress [skip ci]
More WIP
Wibbles to fundeps [skip ci]
Kill off kickOutAfterUnification
More wibbles
Need to remove the unification-count stuff entirely
and do more tidying up -- this commit is mainly for CI
Wibbles solver
Iterate the simples more often than plugins
Start to extend to equalities
Whitespace only
Small improvements
Wibbles
- - - - -
439986e4 by Simon Peyton Jones at 2025-09-30T23:20:04+01:00
Improved error messages from fundep changes
- - - - -
bbaacd31 by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
Wibbles
- - - - -
97283b9d by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
Fix typo
- - - - -
2035ad15 by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
Wibbles
- - - - -
159ebba4 by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
Nuke FunDepOrigin1 and 2
- - - - -
8b3fd33f by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
Wibble
- - - - -
835bf72f by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
More refactoring
- - - - -
59c3742a by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
More tidying up
- - - - -
a2128ccf by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
Yet more
- - - - -
054ff493 by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
Wibbles
- - - - -
8ad73e02 by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
Wibbles [skip ci]
- - - - -
8ac877f2 by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
Naming and comments only [skip ci]
- - - - -
7c60ffbf by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
Progress [skip ci]x
- - - - -
5d56a823 by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
Make it compile
.. with now story on WhatUnifications
- - - - -
fc3c820c by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
Stop putting QLInstVar into the tc_lvl environment [skip ci]
This is really a bug! See (TCAPP2)
Not done yet
- - - - -
32295d2a by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
Now it compiles
- - - - -
e8c68ec1 by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
Accept error message changes
Plus compile time improvement
Metrics: compile_time/bytes allocated
Baseline
Test value New value Change
---------------------- --------------------------------------
T5030(normal) 173,839,232 148,115,248 -14.8% GOOD
hard_hole_fits(normal) 286,768,048 284,015,416 -1.0%
geo. mean -0.2%
minimum -14.8%
maximum +0.3%
Metric Decrease:
T5030
- - - - -
cb488d28 by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
QuickLook's tcInstFun should make instantiation variables directly
tcInstFun must make "instantiation variables", not regular
unification variables, when instantiating function types. That was
previously implemented by a hack: set the /ambient/ level to QLInstTyVar.
But the hack finally bit me, when I was refactoring WhatUnifications.
And it was always wrong: see the now-expunged (TCAPP2) note.
This commit does it right, by making tcInstFun call its own
instantiation functions. That entails a small bit of duplication,
but the result is much, much cleaner.
- - - - -
ea7aff67 by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
Wibbles
- - - - -
4b56a09f by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
Fix
- - - - -
9fd83f21 by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
Wibble Notes
- - - - -
3184c6a4 by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
Wibbles
- - - - -
9a4138e1 by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
Wibble
- - - - -
887202a7 by Simon Peyton Jones at 2025-09-30T23:20:05+01:00
Build implicaiton for constraints from (static e)
This commit addresses #26466, by buiding an implication for the
constraints arising from a (static e) form. The implication has
a special ic_info field of StaticFormSkol, which tells the constraint
solver to use an empty set of Givens.
See (SF3) in Note [Grand plan for static forms]
in GHC.Iface.Tidy.StaticPtrTable
This commit also reinstates an `assert` in GHC.Tc.Solver.Equality.
The test `StaticPtrTypeFamily` was failing with an assertion failure,
but it now works.
- - - - -
91 changed files:
- compiler/GHC/Core/TyCon.hs
- compiler/GHC/Core/Unfold.hs
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Plugins.hs
- compiler/GHC/Iface/Tidy/StaticPtrTable.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Linker/MacOS.hs
- compiler/GHC/Linker/Types.hs
- compiler/GHC/Runtime/Interpreter.hs
- compiler/GHC/Tc/Errors.hs
- compiler/GHC/Tc/Errors/Ppr.hs
- compiler/GHC/Tc/Errors/Types.hs
- compiler/GHC/Tc/Gen/App.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Instance/FunDeps.hs
- compiler/GHC/Tc/Solver.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/Dict.hs
- compiler/GHC/Tc/Solver/Equality.hs
- + compiler/GHC/Tc/Solver/FunDeps.hs
- compiler/GHC/Tc/Solver/InertSet.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Solve.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Types/Origin.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/Zonk/TcType.hs
- compiler/GHC/Types/Basic.hs
- compiler/ghc.cabal.in
- docs/users_guide/profiling.rst
- hadrian/src/Rules/Generate.hs
- libraries/base/changelog.md
- libraries/ghc-internal/src/GHC/Internal/RTS/Flags.hsc
- libraries/ghci/GHCi/Message.hs
- libraries/ghci/GHCi/ObjLink.hs
- libraries/ghci/GHCi/Run.hs
- m4/fptools_set_c_ld_flags.m4
- rts/ExecPage.c
- rts/Interpreter.c
- rts/ProfHeap.c
- rts/RetainerSet.c
- rts/RtsFlags.c
- rts/include/rts/Flags.h
- rts/js/mem.js
- rts/wasm/JSFFI.c
- testsuite/driver/testlib.py
- + testsuite/tests/cross/should_run/T26449.hs
- + testsuite/tests/cross/should_run/all.T
- testsuite/tests/default/default-fail05.stderr
- testsuite/tests/dependent/should_fail/T13135_simple.stderr
- testsuite/tests/deriving/should_fail/T3621.stderr
- testsuite/tests/indexed-types/should_fail/T14369.stderr
- testsuite/tests/indexed-types/should_fail/T1897b.stderr
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout
- testsuite/tests/interface-stability/ghc-experimental-exports.stdout-mingw32
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail10.stderr
- testsuite/tests/parser/should_fail/RecordDotSyntaxFail13.stderr
- testsuite/tests/parser/should_fail/T20654a.stderr
- testsuite/tests/polykinds/T6068.stdout
- testsuite/tests/rep-poly/RepPolyRightSection.stderr
- testsuite/tests/rts/linker/T2615.hs
- testsuite/tests/typecheck/should_compile/T13651.hs
- − testsuite/tests/typecheck/should_compile/T13651.stderr
- + testsuite/tests/typecheck/should_compile/T14745.hs
- testsuite/tests/typecheck/should_compile/all.T
- testsuite/tests/typecheck/should_compile/tc126.hs
- testsuite/tests/typecheck/should_fail/AmbigFDs.hs
- − testsuite/tests/typecheck/should_fail/AmbigFDs.stderr
- testsuite/tests/typecheck/should_fail/FD3.stderr
- testsuite/tests/typecheck/should_fail/FDsFromGivens2.stderr
- testsuite/tests/typecheck/should_fail/T13506.stderr
- testsuite/tests/typecheck/should_fail/T16512a.stderr
- testsuite/tests/typecheck/should_fail/T18851b.hs
- − testsuite/tests/typecheck/should_fail/T18851b.stderr
- testsuite/tests/typecheck/should_fail/T18851c.hs
- − testsuite/tests/typecheck/should_fail/T18851c.stderr
- testsuite/tests/typecheck/should_fail/T19415.stderr
- testsuite/tests/typecheck/should_fail/T19415b.stderr
- testsuite/tests/typecheck/should_fail/T25325.stderr
- testsuite/tests/typecheck/should_fail/T5246.stderr
- testsuite/tests/typecheck/should_fail/T5978.stderr
- testsuite/tests/typecheck/should_fail/T9612.stderr
- testsuite/tests/typecheck/should_fail/all.T
- testsuite/tests/typecheck/should_fail/tcfail143.stderr
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/Link.hs
- utils/jsffi/dyld.mjs
The diff was not included because it is too large.
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/135152ba2b0d9cac0eb7944d355674…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/135152ba2b0d9cac0eb7944d355674…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/T23162-spj] Build implicaiton for constraints from (static e)
by Simon Peyton Jones (@simonpj) 30 Sep '25
by Simon Peyton Jones (@simonpj) 30 Sep '25
30 Sep '25
Simon Peyton Jones pushed to branch wip/T23162-spj at Glasgow Haskell Compiler / GHC
Commits:
135152ba by Simon Peyton Jones at 2025-09-30T23:11:19+01:00
Build implicaiton for constraints from (static e)
This commit addresses #26466, by buiding an implication for the
constraints arising from a (static e) form. The implication has
a special ic_info field of StaticFormSkol, which tells the constraint
solver to use an empty set of Givens.
See (SF3) in Note [Grand plan for static forms]
in GHC.Iface.Tidy.StaticPtrTable
This commit also reinstates an `assert` in GHC.Tc.Solver.Equality.
The test `StaticPtrTypeFamily` was failing with an assertion failure,
but it now works.
- - - - -
11 changed files:
- compiler/GHC/Iface/Tidy/StaticPtrTable.hs
- compiler/GHC/Tc/Gen/Expr.hs
- compiler/GHC/Tc/Solver.hs
- compiler/GHC/Tc/Solver/Default.hs
- compiler/GHC/Tc/Solver/Equality.hs
- compiler/GHC/Tc/Solver/Monad.hs
- compiler/GHC/Tc/Solver/Solve.hs
- compiler/GHC/Tc/Types.hs
- compiler/GHC/Tc/Types/Constraint.hs
- compiler/GHC/Tc/Types/Origin.hs
- compiler/GHC/Tc/Utils/Monad.hs
Changes:
=====================================
compiler/GHC/Iface/Tidy/StaticPtrTable.hs
=====================================
@@ -62,25 +62,35 @@ Here is a running example:
f x = let k = map toUpper
in ...(static k)...
-* The renamer looks for out-of-scope names in the body of the static
+(SF1) The renamer looks for out-of-scope names in the body of the static
form, as always. If all names are in scope, the free variables of the
body are stored in AST at the location of the static form.
-* The typechecker verifies that all free variables occurring in the
+(SF2) The typechecker verifies that all free variables occurring in the
static form are floatable to top level (see Note [Meaning of
IdBindingInfo] in GHC.Tc.Types). In our example, 'k' is floatable.
Even though it is bound in a nested let, we are fine.
See the call to `checkClosedInStaticForm` in the HsStatic case of `tcExpr`.
-* The desugarer replaces the static form with an application of the
+(SF3) The typechecker also wraps the constraints from a static form in an
+ implication, with ic_info = StaticFormSkol. When we try to solve such an
+ implication, we do so with /no Givens/; see `nestImplicTcS`. For example:
+ g :: Show a => StaticPtr (a -> String)
+ g = static show
+ If the @Show a0@ constraint that the body of the static form produces was
+ resolved in the context of the enclosing expression, then the body of the
+ static form wouldn't be closed because the Show dictionary would come from
+ g's context instead of coming from the top level.
+
+(SF4) The desugarer replaces the static form with an application of the
function 'makeStatic' (defined in module GHC.StaticPtr.Internal of
base). So we get
f x = let k = map toUpper
in ...fromStaticPtr (makeStatic location k)...
-* The simplifier runs the FloatOut pass which moves the calls to 'makeStatic'
+(SF5) The simplifier runs the FloatOut pass which moves the calls to 'makeStatic'
to the top level. Thus the FloatOut pass is always executed, even when
optimizations are disabled. So we get
@@ -106,7 +116,7 @@ Here is a running example:
Making the binding exported also has a necessary effect during the
CoreTidy pass.
-* The CoreTidy pass replaces all bindings of the form
+(SF6) The CoreTidy pass replaces all bindings of the form
b = /\ ... -> makeStatic location value
@@ -116,12 +126,12 @@ Here is a running example:
where a distinct key is generated for each binding.
-* If we are compiling to object code we insert a C stub (generated by
+(SF7) If we are compiling to object code we insert a C stub (generated by
sptModuleInitCode) into the final object which runs when the module is loaded,
inserting the static forms defined by the module into the RTS's static pointer
table.
-* If we are compiling for the byte-code interpreter, we instead explicitly add
+(SF8) If we are compiling for the byte-code interpreter, we instead explicitly add
the SPT entries (recorded in CgGuts' cg_spt_entries field) to the interpreter
process' SPT table using the addSptEntry interpreter message. This happens
in upsweep after we have compiled the module (see GHC.Driver.Make.upsweep').
=====================================
compiler/GHC/Tc/Gen/Expr.hs
=====================================
@@ -568,26 +568,30 @@ tcExpr (HsProc x pat cmd) res_ty
tcExpr (HsStatic fvs expr) res_ty
= do { res_ty <- expTypeToType res_ty
; (co, (p_ty, expr_ty)) <- matchExpectedAppTy res_ty
- ; (expr', lie) <- captureConstraints $
- addErrCtxt (StaticFormCtxt expr) $
- tcCheckPolyExprNC expr expr_ty
+ ; (expr', lie) <- captureConstraints $
+ addErrCtxt (StaticFormCtxt expr) $
+ tcCheckPolyExprNC expr expr_ty
+
+ -- Emit an implication that captures the constraints of `expr`,
+ -- but with a `ic_info` of StaticFormSkol
+ -- See #13499 for an explanation of why this is the right thing to do:
+ -- the enclosing skolems must be in scope.
+ ; tc_lvl <- getTcLevel -- No need to bump the level
+ ; (implic, ev_binds) <- buildImplicationFor tc_lvl StaticFormSkol [] [] lie
+ ; emitImplications implic
+ ; let expr'' = mkLHsWrap (mkWpLet ev_binds) expr'
-- Check that the free variables of the static form are closed.
-- It's OK to use nonDetEltsUniqSet here as the only side effects of
-- checkClosedInStaticForm are error messages.
+ -- See (SF2) Note [Grand plan for static forms] in GHC.Iface.Tidy.StaticPtrTable
; mapM_ checkClosedInStaticForm $ nonDetEltsUniqSet fvs
-- Require the type of the argument to be Typeable.
; typeableClass <- tcLookupClass typeableClassName
; typeable_ev <- emitWantedEvVar StaticOrigin $
- mkTyConApp (classTyCon typeableClass)
- [liftedTypeKind, expr_ty]
-
- -- Insert the constraints of the static form in a global list for later
- -- validation. See #13499 for an explanation of why this really isn't the
- -- right thing to do: the enclosing skolems aren't in scope any more!
- -- Static forms really aren't well worked out yet.
- ; emitStaticConstraints lie
+ mkTyConApp (classTyCon typeableClass)
+ [liftedTypeKind, expr_ty]
-- Wrap the static form with the 'fromStaticPtr' call.
; fromStaticPtr <- newMethodFromName StaticOrigin fromStaticPtrName
@@ -595,9 +599,11 @@ tcExpr (HsStatic fvs expr) res_ty
; let wrap = mkWpEvVarApps [typeable_ev] <.> mkWpTyApps [expr_ty]
; loc <- getSrcSpanM
; static_ptr_ty_con <- tcLookupTyCon staticPtrTyConName
- ; return $ mkHsWrapCo co $ HsApp noExtField
- (L (noAnnSrcSpan loc) $ mkHsWrap wrap fromStaticPtr)
- (L (noAnnSrcSpan loc) (HsStatic (fvs, mkTyConApp static_ptr_ty_con [expr_ty]) expr'))
+ ; return $ mkHsWrapCo co $
+ HsApp noExtField
+ (L (noAnnSrcSpan loc) $ mkHsWrap wrap fromStaticPtr)
+ (L (noAnnSrcSpan loc) (HsStatic (fvs, mkTyConApp static_ptr_ty_con [expr_ty])
+ expr''))
}
tcExpr (HsEmbTy _ _) _ = failWith (TcRnIllegalTypeExpr TypeKeywordSyntax)
=====================================
compiler/GHC/Tc/Solver.hs
=====================================
@@ -102,17 +102,14 @@ captureTopConstraints :: TcM a -> TcM (a, WantedConstraints)
-- calling this, so that the reportUnsolved has access to the most
-- complete GlobalRdrEnv
captureTopConstraints thing_inside
- = do { static_wc_var <- TcM.newTcRef emptyWC ;
- ; (mb_res, lie) <- TcM.updGblEnv (\env -> env { tcg_static_wc = static_wc_var } ) $
- TcM.tryCaptureConstraints thing_inside
- ; stWC <- TcM.readTcRef static_wc_var
+ = do { (mb_res, lie) <- TcM.tryCaptureConstraints thing_inside
-- See GHC.Tc.Utils.Monad Note [Constraints and errors]
-- If the thing_inside threw an exception, but generated some insoluble
-- constraints, report the latter before propagating the exception
-- Otherwise they will be lost altogether
; case mb_res of
- Just res -> return (res, lie `andWC` stWC)
+ Just res -> return (res, lie)
Nothing -> do { _ <- simplifyTop lie; failM } }
-- This call to simplifyTop is the reason
-- this function is here instead of GHC.Tc.Utils.Monad
=====================================
compiler/GHC/Tc/Solver/Default.hs
=====================================
@@ -275,13 +275,13 @@ solveImplicationUsingUnsatGiven :: (EvVar, Type) -> Implication -> TcS Implicati
solveImplicationUsingUnsatGiven
unsat_given@(given_ev,_)
impl@(Implic { ic_wanted = wtd, ic_tclvl = tclvl, ic_binds = ev_binds_var
- , ic_need_implic = inner })
+ , ic_need_implic = inner, ic_info = skol_info })
| isCoEvBindsVar ev_binds_var
-- We can't use Unsatisfiable evidence in kinds.
-- See Note [Coercion evidence only] in GHC.Tc.Types.Evidence.
= return impl
| otherwise
- = do { wcs <- nestImplicTcS ev_binds_var tclvl $ go_wc wtd
+ = do { wcs <- nestImplicTcS skol_info ev_binds_var tclvl $ go_wc wtd
; setImplicationStatus $
impl { ic_wanted = wcs
, ic_need_implic = inner `extendEvNeedSet` given_ev } }
@@ -1135,7 +1135,7 @@ disambigProposalSequences orig_wanteds wanteds proposalSequences allConsistent
; tclvl <- TcS.getTcLevel
-- Step (3) in Note [How type-class constraints are defaulted]
; successes <- fmap catMaybes $
- nestImplicTcS fake_ev_binds_var (pushTcLevel tclvl) $
+ nestImplicTcS DefaultSkol fake_ev_binds_var (pushTcLevel tclvl) $
mapM firstSuccess proposalSequences
; traceTcS "disambigProposalSequences {" (vcat [ ppr wanteds
, ppr proposalSequences
=====================================
compiler/GHC/Tc/Solver/Equality.hs
=====================================
@@ -1681,7 +1681,6 @@ canEqCanLHSHetero ev eq_rel swapped lhs1 ps_xi1 ki1 xi2 ps_xi2 ki2
in unSwap swapped (uType uenv') ki1 ki2
-- mkKindEqLoc: any new constraints, arising from the kind
-- unification, say they thay come from unifying xi1~xi2
- -- ...AndEmit: emit any unsolved equalities
-- Kick out any inert constraints mentioning the unified variables
; kickOutAfterUnification unifs
@@ -1697,14 +1696,13 @@ canEqCanLHSHetero ev eq_rel swapped lhs1 ps_xi1 ki1 xi2 ps_xi2 ki2
-- Emit the deferred constraints
do { emitChildEqs ev eqs
--- This assert is commented out because of #26453. Reinstate it when #26453 is fixed
--- ; assertPpr (not (isEmptyCts eqs))
--- (vcat [ppr ev, ppr ki1, ppr ki2, ppr unifs, ppr eqs]) $
--- -- assert: the constraints won't be empty because the two kinds differ,
--- -- and there are no unifications, so we must have emitted one or
--- -- more constraints
+ ; assertPpr (not (isEmptyCts eqs))
+ (vcat [ppr ev, ppr ki1, ppr ki2, ppr unifs, ppr eqs]) $
+ -- assert: the constraints won't be empty because the two kinds differ,
+ -- and there are no unifications, so we must have emitted one or
+ -- more constraints
- ; finish (rewriterSetFromCts eqs) kind_co }}
+ finish (rewriterSetFromCts eqs) kind_co }}
-- rewriterSetFromCts: record in the /type/ unification xi1~xi2 that
-- it has been rewritten by any (unsolved) constraints in `cts`; that
-- stops xi1~xi2 from unifying until `cts` are solved. See (EIK2).
=====================================
compiler/GHC/Tc/Solver/Monad.hs
=====================================
@@ -1199,20 +1199,12 @@ setTcLevelTcS :: TcLevel -> TcS a -> TcS a
setTcLevelTcS lvl (TcS thing_inside)
= TcS $ \ env -> TcM.setTcLevel lvl (thing_inside env)
-nestImplicTcS :: EvBindsVar
+nestImplicTcS :: SkolemInfoAnon -> EvBindsVar
-> TcLevel -> TcS a
-> TcS a
-nestImplicTcS ev_binds_var inner_tclvl (TcS thing_inside)
+nestImplicTcS skol_info ev_binds_var inner_tclvl (TcS thing_inside)
= TcS $ \ env@(TcSEnv { tcs_inerts = old_inert_var }) ->
- do { inerts <- TcM.readTcRef old_inert_var
-
- -- resetInertcans: initialise the inert_cans from the inert_givens of the
- -- parent so that the child is not polluted with the parent's inert Wanteds
- -- See Note [trySolveImplication] in GHC.Tc.Solver.Solve
- -- All other InertSet fields are inherited
- ; let nest_inert = pushCycleBreakerVarStack $
- resetInertCans $
- inerts
+ do { nest_inert <- mk_nested_inert_set skol_info old_inert_var
; new_inert_var <- TcM.newTcRef nest_inert
; new_wl_var <- TcM.newTcRef emptyWorkList
; let nest_env = env { tcs_ev_binds = ev_binds_var
@@ -1230,6 +1222,25 @@ nestImplicTcS ev_binds_var inner_tclvl (TcS thing_inside)
; checkForCyclicBinds ev_binds
#endif
; return res }
+ where
+ mk_nested_inert_set skol_info old_inert_var
+ -- For an implication that comes from a static form (static e),
+ -- start with a completely empty inert set; in particular, no Givens
+ -- See (SF3) in Note [Grand plan for static forms]
+ -- in GHC.Iface.Tidy.StaticPtrTable
+ | StaticFormSkol <- skol_info
+ = return (emptyInertSet inner_tclvl)
+
+ | otherwise
+ = do { inerts <- TcM.readTcRef old_inert_var
+
+ -- resetInertCans: initialise the inert_cans from the inert_givens of the
+ -- parent so that the child is not polluted with the parent's inert Wanteds
+ -- See Note [trySolveImplication] in GHC.Tc.Solver.Solve
+ -- All other InertSet fields are inherited
+ ; return (pushCycleBreakerVarStack $
+ resetInertCans $
+ inerts) }
nestFunDepsTcS :: TcS a -> TcS a
nestFunDepsTcS (TcS thing_inside)
=====================================
compiler/GHC/Tc/Solver/Solve.hs
=====================================
@@ -394,7 +394,7 @@ trySolveImplication (Implic { ic_tclvl = tclvl
, ic_wanted = wanteds
, ic_env = ct_loc_env
, ic_info = info })
- = nestImplicTcS ev_binds_var tclvl $
+ = nestImplicTcS info ev_binds_var tclvl $
do { let loc = mkGivenLoc tclvl info ct_loc_env
givens = mkGivens loc given_ids
; solveSimpleGivens givens
@@ -427,7 +427,7 @@ solveImplication imp@(Implic { ic_tclvl = tclvl
-- Solve the nested constraints
; (has_given_eqs, given_insols, residual_wanted)
- <- nestImplicTcS ev_binds_var tclvl $
+ <- nestImplicTcS info ev_binds_var tclvl $
do { let loc = mkGivenLoc tclvl info ct_loc_env
givens = mkGivens loc given_ids
; solveSimpleGivens givens
=====================================
compiler/GHC/Tc/Types.hs
=====================================
@@ -689,9 +689,6 @@ data TcGblEnv
tcg_top_loc :: RealSrcSpan,
-- ^ The RealSrcSpan this module came from
- tcg_static_wc :: TcRef WantedConstraints,
- -- ^ Wanted constraints of static forms.
- -- See Note [Constraints in static forms].
tcg_complete_matches :: !CompleteMatches,
-- ^ Complete matches defined in this module.
@@ -706,27 +703,6 @@ data TcGblEnv
-- Definition sites of orphan identities will be identity modules, not semantic
-- modules.
--- Note [Constraints in static forms]
--- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
---
--- When a static form produces constraints like
---
--- f :: StaticPtr (Bool -> String)
--- f = static show
---
--- we collect them in tcg_static_wc and resolve them at the end
--- of type checking. They need to be resolved separately because
--- we don't want to resolve them in the context of the enclosing
--- expression. Consider
---
--- g :: Show a => StaticPtr (a -> String)
--- g = static show
---
--- If the @Show a0@ constraint that the body of the static form produces was
--- resolved in the context of the enclosing expression, then the body of the
--- static form wouldn't be closed because the Show dictionary would come from
--- g's context instead of coming from the top level.
-
tcVisibleOrphanMods :: TcGblEnv -> ModuleSet
tcVisibleOrphanMods tcg_env
= mkModuleSet (tcg_mod tcg_env : imp_orphs (tcg_imports tcg_env))
=====================================
compiler/GHC/Tc/Types/Constraint.hs
=====================================
@@ -1447,6 +1447,9 @@ data Implication
ic_info :: SkolemInfoAnon, -- See Note [Skolems in an implication]
-- See Note [Shadowing in a constraint]
+ -- NB: Mostly ic_info is just there to help with error messages
+ -- but StaticFormSkol has a deeper significance; see (SF3) in
+ -- Note [Grand plan for static forms] in GHC.Iface.Tidy.StaticPtrTable
ic_skols :: [TcTyVar], -- Introduced skolems; always skolem TcTyVars
-- Their level numbers should be precisely ic_tclvl
=====================================
compiler/GHC/Tc/Types/Origin.hs
=====================================
@@ -334,6 +334,11 @@ data SkolemInfoAnon
| UnkSkol CallStack
+ | DefaultSkol -- Used (only) during defaulting
+
+ | StaticFormSkol -- Attached to an implication constraint that captures
+ -- the constraints from (static e)
+
-- | Use this when you can't specify a helpful origin for
-- some skolem type variable.
@@ -393,6 +398,8 @@ pprSkolInfo ReifySkol = text "the type being reified"
pprSkolInfo RuntimeUnkSkol = text "Unknown type from GHCi runtime"
pprSkolInfo ArrowReboundIfSkol = text "the expected type of a rebound if-then-else command"
+pprSkolInfo StaticFormSkol = text "a static expression"
+pprSkolInfo DefaultSkol = text "a constraint being defaulted"
-- unkSkol
-- For type variables the others are dealt with by pprSkolTvBinding.
=====================================
compiler/GHC/Tc/Utils/Monad.hs
=====================================
@@ -108,7 +108,7 @@ module GHC.Tc.Utils.Monad(
getTcEvBindsMap, setTcEvBindsMap, updTcEvBinds,
getTcEvTyCoVars, chooseUniqueOccTc,
getConstraintVar, setConstraintVar,
- emitConstraints, emitStaticConstraints, emitSimple, emitSimples,
+ emitConstraints, emitSimple, emitSimples,
emitImplication, emitImplications, ensureReflMultiplicityCo,
emitDelayedErrors, emitHole, emitHoles, emitNotConcreteError,
discardConstraints, captureConstraints, tryCaptureConstraints,
@@ -296,7 +296,6 @@ initTcGblEnv hsc_env hsc_src keep_rn_syntax mod loc =
; zany_n_var <- newIORef 0
; dependent_files_var <- newIORef []
; dependent_dirs_var <- newIORef []
- ; static_wc_var <- newIORef emptyWC
; cc_st_var <- newIORef newCostCentreState
; th_topdecls_var <- newIORef []
; th_foreign_files_var <- newIORef []
@@ -396,7 +395,6 @@ initTcGblEnv hsc_env hsc_src keep_rn_syntax mod loc =
, tcg_defaulting_plugins = []
, tcg_hf_plugins = []
, tcg_top_loc = loc
- , tcg_static_wc = static_wc_var
, tcg_complete_matches = []
, tcg_cc_st = cc_st_var
, tcg_next_wrapper_num = next_wrapper_num
@@ -1984,11 +1982,6 @@ getConstraintVar = do { env <- getLclEnv; return (tcl_lie env) }
setConstraintVar :: TcRef WantedConstraints -> TcM a -> TcM a
setConstraintVar lie_var = updLclEnv (\ env -> env { tcl_lie = lie_var })
-emitStaticConstraints :: WantedConstraints -> TcM ()
-emitStaticConstraints static_lie
- = do { gbl_env <- getGblEnv
- ; updTcRef (tcg_static_wc gbl_env) (`andWC` static_lie) }
-
emitConstraints :: WantedConstraints -> TcM ()
emitConstraints ct
| isEmptyWC ct
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/135152ba2b0d9cac0eb7944d355674c…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/commit/135152ba2b0d9cac0eb7944d355674c…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
30 Sep '25
Cheng Shao pushed new branch wip/rm-testsuite-ci-flag at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/rm-testsuite-ci-flag
You're receiving this email because of your account on gitlab.haskell.org.
1
0
[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 7 commits: rts: Fix lost wakeups in threadPaused for threads blocked on black holes
by Marge Bot (@marge-bot) 30 Sep '25
by Marge Bot (@marge-bot) 30 Sep '25
30 Sep '25
Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC
Commits:
06108198 by Luite Stegeman at 2025-09-30T14:09:24-04:00
rts: Fix lost wakeups in threadPaused for threads blocked on black holes
The lazy blackholing code in threadPaused could overwrite closures
that were already eagerly blackholed, and as such wouldn't have a
marked update frame. If the black hole was overwritten by its
original owner, this would lead to an undetected collision, and
the contents of any existing blocking queue being lost.
This adds a check for eagerly blackholed closures and avoids
overwriting their contents.
Fixes #26324
- - - - -
4bb1576e by Luite Stegeman at 2025-09-30T14:09:24-04:00
rts: push the correct update frame in stg_AP_STACK
The frame contains an eager black hole (__stg_EAGER_BLACKHOLE_info) so
we should push an stg_bh_upd_frame_info instead of an stg_upd_frame_info.
- - - - -
9f1423b8 by Cheng Shao at 2025-09-30T14:09:25-04:00
ghci: fix lookupSymbolInDLL behavior on wasm
This patch fixes lookupSymbolInDLL behavior on wasm to return Nothing
instead of throwing. On wasm, we only have lookupSymbol, and the
driver would attempt to call lookupSymbolInDLL first before falling
back to lookupSymbol, so lookupSymbolInDLL needs to return Nothing
gracefully for the fallback behavior to work.
- - - - -
583d3d53 by Cheng Shao at 2025-09-30T14:09:25-04:00
hadrian/compiler: enable internal-interpreter for ghc library in wasm stage1
This commit enables the internal-interpreter flag for ghc library in
wasm stage1, as well as other minor adjustments to make it actually
possible to launch a ghc api session that makes use of the internal
interpreter. Closes #26431 #25400.
- - - - -
bb886749 by Cheng Shao at 2025-09-30T14:09:25-04:00
testsuite: add T26431 test case
This commit adds T26431 to testsuite/tests/ghci-wasm which goes
through the complete bytecode compilation/linking/running pipeline in
wasm, so to witness that the ghc shared library in wasm have full
support for internal-interpreter.
- - - - -
74e01719 by Matthew Pickering at 2025-09-30T14:09:26-04:00
driver: Load bytecode static pointer entries during linking
Previously the entries were loaded too eagerly, during upsweep, but we
should delay loading them until we know that the relevant bytecode
object is demanded.
Towards #25230
- - - - -
51c7def9 by Cheng Shao at 2025-09-30T14:09:27-04:00
autoconf/ghc-toolchain: remove obsolete C99 check
This patch removes obsolete c99 check from autoconf/ghc-toolchain. For
all toolchain & platform combination we support, gnu11 or above is
already supported without any -std flag required, and our RTS already
required C11 quite a few years ago, so the C99 check is completely
pointless.
- - - - -
21 changed files:
- compiler/GHC.hs
- compiler/GHC/Cmm/Parser.y
- compiler/GHC/Driver/Main.hs
- compiler/GHC/Driver/Make.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Iface/Tidy/StaticPtrTable.hs
- compiler/GHC/Linker/Loader.hs
- compiler/GHC/Runtime/Interpreter/Types.hs
- configure.ac
- distrib/configure.ac.in
- hadrian/src/Settings/Packages.hs
- libraries/ghci/GHCi/ObjLink.hs
- m4/fp_cmm_cpp_cmd_with_args.m4
- − m4/fp_set_cflags_c99.m4
- rts/Apply.cmm
- rts/ThreadPaused.c
- + testsuite/tests/ghci-wasm/T26431.hs
- + testsuite/tests/ghci-wasm/T26431.stdout
- testsuite/tests/ghci-wasm/all.T
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cc.hs
- utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cpp.hs
Changes:
=====================================
compiler/GHC.hs
=====================================
@@ -716,17 +716,14 @@ setTopSessionDynFlags dflags = do
-- see Note [Target code interpreter]
interp <- if
+#if !defined(wasm32_HOST_ARCH)
-- Wasm dynamic linker
| ArchWasm32 <- platformArch $ targetPlatform dflags
-> do
s <- liftIO $ newMVar InterpPending
loader <- liftIO Loader.uninitializedLoader
dyld <- liftIO $ makeAbsolute $ topDir dflags </> "dyld.mjs"
-#if defined(wasm32_HOST_ARCH)
- let libdir = sorry "cannot spawn child process on wasm"
-#else
libdir <- liftIO $ last <$> Loader.getGccSearchDirectory logger dflags "libraries"
-#endif
let profiled = ways dflags `hasWay` WayProf
way_tag = if profiled then "_p" else ""
let cfg =
@@ -747,6 +744,7 @@ setTopSessionDynFlags dflags = do
wasmInterpUnitState = ue_homeUnitState $ hsc_unit_env hsc_env
}
pure $ Just $ Interp (ExternalInterp $ ExtWasm $ ExtInterpState cfg s) loader lookup_cache
+#endif
-- JavaScript interpreter
| ArchJavaScript <- platformArch (targetPlatform dflags)
=====================================
compiler/GHC/Cmm/Parser.y
=====================================
@@ -1321,6 +1321,7 @@ stmtMacros = listToUFM [
( fsLit "PROF_HEADER_CREATE", \[e] -> profHeaderCreate e ),
( fsLit "PUSH_UPD_FRAME", \[sp,e] -> emitPushUpdateFrame sp e ),
+ ( fsLit "PUSH_BH_UPD_FRAME", \[sp,e] -> emitPushBHUpdateFrame sp e ),
( fsLit "SET_HDR", \[ptr,info,ccs] ->
emitSetDynHdr ptr info ccs ),
( fsLit "TICK_ALLOC_PRIM", \[hdr,goods,slop] ->
@@ -1336,6 +1337,10 @@ emitPushUpdateFrame :: CmmExpr -> CmmExpr -> FCode ()
emitPushUpdateFrame sp e = do
emitUpdateFrame sp mkUpdInfoLabel e
+emitPushBHUpdateFrame :: CmmExpr -> CmmExpr -> FCode ()
+emitPushBHUpdateFrame sp e = do
+ emitUpdateFrame sp mkBHUpdInfoLabel e
+
pushStackFrame :: [CmmParse CmmExpr] -> CmmParse () -> CmmParse ()
pushStackFrame fields body = do
profile <- getProfile
=====================================
compiler/GHC/Driver/Main.hs
=====================================
@@ -102,7 +102,6 @@ module GHC.Driver.Main
, dumpIfaceStats
, ioMsgMaybe
, showModuleIndex
- , hscAddSptEntries
, writeInterfaceOnlyMode
, loadByteCode
, genModDetails
@@ -2515,9 +2514,6 @@ hscParsedDecls hsc_env decls = runInteractiveHsc hsc_env $ do
let src_span = srcLocSpan interactiveSrcLoc
_ <- liftIO $ loadDecls interp hsc_env src_span linkable
- {- Load static pointer table entries -}
- liftIO $ hscAddSptEntries hsc_env (cg_spt_entries tidy_cg)
-
let tcs = filterOut isImplicitTyCon (mg_tcs simpl_mg)
patsyns = mg_patsyns simpl_mg
@@ -2539,18 +2535,6 @@ hscParsedDecls hsc_env decls = runInteractiveHsc hsc_env $ do
fam_insts defaults fix_env
return (new_tythings, new_ictxt)
--- | Load the given static-pointer table entries into the interpreter.
--- See Note [Grand plan for static forms] in "GHC.Iface.Tidy.StaticPtrTable".
-hscAddSptEntries :: HscEnv -> [SptEntry] -> IO ()
-hscAddSptEntries hsc_env entries = do
- let interp = hscInterp hsc_env
- let add_spt_entry :: SptEntry -> IO ()
- add_spt_entry (SptEntry n fpr) = do
- -- These are only names from the current module
- (val, _, _) <- loadName interp hsc_env n
- addSptEntry interp fpr val
- mapM_ add_spt_entry entries
-
{-
Note [Fixity declarations in GHCi]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=====================================
compiler/GHC/Driver/Make.hs
=====================================
@@ -56,8 +56,6 @@ import GHC.Tc.Utils.Monad ( initIfaceCheck, concatMapM )
import GHC.Runtime.Interpreter
import qualified GHC.Linker.Loader as Linker
-import GHC.Linker.Types
-
import GHC.Driver.Config.Diagnostic
import GHC.Driver.Pipeline
@@ -72,8 +70,6 @@ import GHC.Driver.MakeSem
import GHC.Driver.Downsweep
import GHC.Driver.MakeAction
-import GHC.ByteCode.Types
-
import GHC.Iface.Load ( cannotFindModule, readIface )
import GHC.IfaceToCore ( typecheckIface )
import GHC.Iface.Recomp ( RecompileRequired(..), CompileReason(..) )
@@ -1232,31 +1228,9 @@ upsweep_mod :: HscEnv
upsweep_mod hsc_env mHscMessage old_hmi summary mod_index nmods = do
hmi <- compileOne' mHscMessage hsc_env summary
mod_index nmods (hm_iface <$> old_hmi) (maybe emptyHomeModInfoLinkable hm_linkable old_hmi)
-
- -- MP: This is a bit janky, because before you add the entries you have to extend the HPT with the module
- -- you just compiled. Another option, would be delay adding anything until after upsweep has finished, but I
- -- am unsure if this is sound (wrt running TH splices for example).
- -- This function only does anything if the linkable produced is a BCO, which
- -- used to only happen with the bytecode backend, but with
- -- @-fprefer-byte-code@, @HomeModInfo@ has bytecode even when generating
- -- object code, see #25230.
hscInsertHPT hmi hsc_env
- addSptEntries (hsc_env)
- (homeModInfoByteCode hmi)
-
return hmi
--- | Add the entries from a BCO linkable to the SPT table, see
--- See Note [Grand plan for static forms] in GHC.Iface.Tidy.StaticPtrTable.
-addSptEntries :: HscEnv -> Maybe Linkable -> IO ()
-addSptEntries hsc_env mlinkable =
- hscAddSptEntries hsc_env
- [ spt
- | linkable <- maybeToList mlinkable
- , bco <- linkableBCOs linkable
- , spt <- bc_spt_entries bco
- ]
-
-- Note [When source is considered modified]
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
=====================================
compiler/GHC/Driver/Session.hs
=====================================
@@ -3763,12 +3763,17 @@ makeDynFlagsConsistent dflags
-- only supports dynamic code
| LinkInMemory <- ghcLink dflags
, sTargetRTSLinkerOnlySupportsSharedLibs $ settings dflags
+#if defined(HAVE_INTERNAL_INTERPRETER)
+ , not (ways dflags `hasWay` WayDyn)
+#else
, not (ways dflags `hasWay` WayDyn && gopt Opt_ExternalInterpreter dflags)
+#endif
= flip loopNoWarn "Forcing dynamic way because target RTS linker only supports dynamic code" $
- -- See checkOptions, -fexternal-interpreter is
- -- required when using --interactive with a non-standard
- -- way (-prof, -static, or -dynamic).
+#if !defined(HAVE_INTERNAL_INTERPRETER)
+ -- Force -fexternal-interpreter if internal-interpreter is not
+ -- available at this stage
setGeneralFlag' Opt_ExternalInterpreter $
+#endif
addWay' WayDyn dflags
| LinkInMemory <- ghcLink dflags
=====================================
compiler/GHC/Iface/Tidy/StaticPtrTable.hs
=====================================
@@ -124,7 +124,7 @@ Here is a running example:
* If we are compiling for the byte-code interpreter, we instead explicitly add
the SPT entries (recorded in CgGuts' cg_spt_entries field) to the interpreter
process' SPT table using the addSptEntry interpreter message. This happens
- in upsweep after we have compiled the module (see GHC.Driver.Make.upsweep').
+ when the bytecode object is linked in `dynLinkBCOs`.
-}
import GHC.Prelude
=====================================
compiler/GHC/Linker/Loader.hs
=====================================
@@ -718,6 +718,7 @@ loadDecls interp hsc_env span linkable = do
let ce2 = extendClosureEnv (closure_env le2) nms_fhvs
!pls2 = pls { linker_env = le2 { closure_env = ce2 }
, linked_breaks = lb2 }
+ mapM_ (linkSptEntry interp ce2) (concatMap bc_spt_entries cbcs)
return (pls2, (nms_fhvs, links_needed, units_needed))
where
cbcs = linkableBCOs linkable
@@ -951,10 +952,28 @@ dynLinkBCOs interp pls bcos = do
-- Wrap finalizers on the ones we want to keep
new_binds <- makeForeignNamedHValueRefs interp to_add
+
let ce2 = extendClosureEnv (closure_env le2) new_binds
+
+ -- Add SPT entries
+ mapM_ (linkSptEntry interp ce2) (concatMap bc_spt_entries cbcs)
+
return $! pls1 { linker_env = le2 { closure_env = ce2 }
, linked_breaks = lb2 }
+-- | Register SPT entries for this module in the interpreter
+-- Assumes that the name from the SPT has already been loaded into the interpreter.
+linkSptEntry :: Interp -> ClosureEnv -> SptEntry -> IO ()
+linkSptEntry interp ce (SptEntry name fpr) = do
+ case lookupNameEnv ce name of
+ -- The SPT entries only point to locally defined names, which should have already been
+ -- loaded into the interpreter before this function is called.
+ Nothing -> pprPanic "linkSptEntry" (ppr name)
+ Just (_, hval) -> addSptEntry interp fpr hval
+
+
+
+
-- Link a bunch of BCOs and return references to their values
linkSomeBCOs :: Interp
-> PkgsLoaded
@@ -1614,6 +1633,9 @@ gccSearchDirCache = unsafePerformIO $ newIORef []
-- which dominate a large percentage of startup time on Windows.
getGccSearchDirectory :: Logger -> DynFlags -> String -> IO [FilePath]
getGccSearchDirectory logger dflags key = do
+#if defined(wasm32_HOST_ARCH)
+ pure []
+#else
cache <- readIORef gccSearchDirCache
case lookup key cache of
Just x -> return x
@@ -1640,6 +1662,7 @@ getGccSearchDirectory logger dflags key = do
x:_ -> case break (=='=') x of
(_ , []) -> []
(_, (_:xs)) -> xs
+#endif
-- | Get a list of system search directories, this to alleviate pressure on
-- the findSysDll function.
=====================================
compiler/GHC/Runtime/Interpreter/Types.hs
=====================================
@@ -214,7 +214,7 @@ data JSInterpConfig = JSInterpConfig
data WasmInterpConfig = WasmInterpConfig
{ wasmInterpDyLD :: !FilePath -- ^ Location of dyld.mjs script
- , wasmInterpLibDir :: FilePath -- ^ wasi-sdk sysroot libdir containing libc.so, etc
+ , wasmInterpLibDir :: !FilePath -- ^ wasi-sdk sysroot libdir containing libc.so, etc
, wasmInterpOpts :: ![String] -- ^ Additional command line arguments for iserv
-- wasm ghci browser mode
=====================================
configure.ac
=====================================
@@ -448,11 +448,6 @@ AC_SUBST([CmmCPPCmd])
AC_SUBST([CmmCPPArgs])
AC_SUBST([CmmCPPSupportsG0])
-FP_SET_CFLAGS_C99([CC],[CFLAGS],[CPPFLAGS])
-FP_SET_CFLAGS_C99([CC_STAGE0],[CONF_CC_OPTS_STAGE0],[CONF_CPP_OPTS_STAGE0])
-FP_SET_CFLAGS_C99([CC],[CONF_CC_OPTS_STAGE1],[CONF_CPP_OPTS_STAGE1])
-FP_SET_CFLAGS_C99([CC],[CONF_CC_OPTS_STAGE2],[CONF_CPP_OPTS_STAGE2])
-
dnl ** Do we have a compatible emsdk version?
dnl --------------------------------------------------------------
EMSDK_VERSION("3.1.20", "", "")
=====================================
distrib/configure.ac.in
=====================================
@@ -163,11 +163,6 @@ AC_SUBST([CmmCPPCmd])
AC_SUBST([CmmCPPArgs])
AC_SUBST([CmmCPPSupportsG0])
-FP_SET_CFLAGS_C99([CC],[CFLAGS],[CPPFLAGS])
-dnl FP_SET_CFLAGS_C99([CC_STAGE0],[CONF_CC_OPTS_STAGE0],[CONF_CPP_OPTS_STAGE0])
-FP_SET_CFLAGS_C99([CC],[CONF_CC_OPTS_STAGE1],[CONF_CPP_OPTS_STAGE1])
-FP_SET_CFLAGS_C99([CC],[CONF_CC_OPTS_STAGE2],[CONF_CPP_OPTS_STAGE2])
-
dnl ** Which ld to use?
dnl --------------------------------------------------------------
FIND_LD([$target],[GccUseLdOpt])
=====================================
hadrian/src/Settings/Packages.hs
=====================================
@@ -82,15 +82,18 @@ packageArgs = do
]
, builder (Cabal Flags) ? mconcat
- -- For the ghc library, internal-interpreter only makes
- -- sense when we're not cross compiling. For cross GHC,
- -- external interpreter is used for loading target code
- -- and internal interpreter is supposed to load native
- -- code for plugins (!7377), however it's unfinished work
- -- (#14335) and completely untested in CI for cross
- -- backends at the moment, so we might as well disable it
- -- for cross GHC.
- [ andM [expr (ghcWithInterpreter stage), notCross] `cabalFlag` "internal-interpreter"
+ -- In order to enable internal-interpreter for the ghc
+ -- library:
+ --
+ -- 1. ghcWithInterpreter must be True ("Use interpreter" =
+ -- "YES")
+ -- 2. For non-cross case it can be enabled
+ -- 3. For cross case, disable for stage0 since that runs
+ -- on the host and must rely on external interpreter to
+ -- load target code, otherwise enable for stage1 since
+ -- that runs on the target and can use target's own
+ -- ghci object linker
+ [ andM [expr (ghcWithInterpreter stage), orM [notCross, stage1]] `cabalFlag` "internal-interpreter"
, orM [ notM cross, haveCurses ] `cabalFlag` "terminfo"
, arg "-build-tool-depends"
, flag UseLibzstd `cabalFlag` "with-libzstd"
=====================================
libraries/ghci/GHCi/ObjLink.hs
=====================================
@@ -113,8 +113,7 @@ foreign import javascript unsafe "__ghc_wasm_jsffi_dyld.lookupSymbol($1)"
js_lookupSymbol :: JSString -> IO (Ptr a)
lookupSymbolInDLL :: Ptr LoadedDLL -> String -> IO (Maybe (Ptr a))
-lookupSymbolInDLL _ sym =
- throwIO $ ErrorCall $ "lookupSymbolInDLL: unsupported on wasm for " <> sym
+lookupSymbolInDLL _ _ = pure Nothing
resolveObjs :: IO Bool
resolveObjs = pure True
=====================================
m4/fp_cmm_cpp_cmd_with_args.m4
=====================================
@@ -56,27 +56,6 @@ else
AC_MSG_RESULT([no])
fi
-AC_MSG_CHECKING([the C-- preprocessor for C99 support])
-cat > conftest.c <<EOF
-#include <stdio.h>
-#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
-# error "Compiler does not advertise C99 conformance"
-#endif
-EOF
-if "$CMM_CPP_CMD" $CMM_CPP_ARGS conftest.c -o conftest -g0 >/dev/null 2>&1; then
- AC_MSG_RESULT([yes])
-else
- # Try -std=gnu99
- if "$CMM_CPP_CMD" -std=gnu99 $CMM_CPP_ARGS conftest.c -o conftest -g0 >/dev/null 2>&1; then
- $3="-std=gnu99 $$3"
- AC_MSG_RESULT([needs -std=gnu99])
- else
- AC_MSG_ERROR([C99-compatible compiler needed])
- fi
-fi
-rm -f conftest.c conftest.o conftest
-
-
$2="$CMM_CPP_CMD"
$3="$$3 $CMM_CPP_ARGS"
@@ -85,4 +64,3 @@ unset CMM_CPP_CMD
unset CMM_CPP_ARGS
])
-
=====================================
m4/fp_set_cflags_c99.m4 deleted
=====================================
@@ -1,38 +0,0 @@
-# FP_SET_CFLAGS_C99
-# ----------------------------------
-# figure out which CFLAGS are needed to place the compiler into C99 mode
-# $1 is name of CC variable (unmodified)
-# $2 is name of CC flags variable (augmented if needed)
-# $3 is name of CPP flags variable (augmented if needed)
-AC_DEFUN([FP_SET_CFLAGS_C99],
-[
- dnl save current state of AC_PROG_CC_C99
- FP_COPY_SHELLVAR([CC],[fp_save_CC])
- FP_COPY_SHELLVAR([CFLAGS],[fp_save_CFLAGS])
- FP_COPY_SHELLVAR([CPPFLAGS],[fp_save_CPPFLAGS])
- FP_COPY_SHELLVAR([ac_cv_prog_cc_c99],[fp_save_cc_c99])
- dnl set local state
- CC="$$1"
- CFLAGS="$$2"
- CPPFLAGS="$$3"
- unset ac_cv_prog_cc_c99
- dnl perform detection
- AC_PROG_CC_C99
- fp_cc_c99="$ac_cv_prog_cc_c99"
- case "x$ac_cv_prog_cc_c99" in
- x) ;; # noop
- xno) AC_MSG_ERROR([C99-compatible compiler needed]) ;;
- *) $2="$$2 $ac_cv_prog_cc_c99"
- $3="$$3 $ac_cv_prog_cc_c99"
- ;;
- esac
- dnl restore saved state
- FP_COPY_SHELLVAR([fp_save_CC],[CC])
- FP_COPY_SHELLVAR([fp_save_CFLAGS],[CFLAGS])
- FP_COPY_SHELLVAR([fp_save_CPPFLAGS],[CPPFLAGS])
- FP_COPY_SHELLVAR([fp_save_cc_c99],[ac_cv_prog_cc_c99])
- dnl cleanup
- unset fp_save_CC
- unset fp_save_CFLAGS
- unset fp_save_cc_c99
-])
=====================================
rts/Apply.cmm
=====================================
@@ -699,7 +699,7 @@ INFO_TABLE(stg_AP_STACK,/*special layout*/0,0,AP_STACK,"AP_STACK","AP_STACK")
/* ensure there is at least AP_STACK_SPLIM words of headroom available
* after unpacking the AP_STACK. See bug #1466 */
- PUSH_UPD_FRAME(Sp - SIZEOF_StgUpdateFrame, R1);
+ PUSH_BH_UPD_FRAME(Sp - SIZEOF_StgUpdateFrame, R1);
Sp = Sp - SIZEOF_StgUpdateFrame - WDS(Words);
TICK_ENT_AP();
=====================================
rts/ThreadPaused.c
=====================================
@@ -15,6 +15,7 @@
#include "RaiseAsync.h"
#include "Trace.h"
#include "Threads.h"
+#include "Messages.h"
#include "sm/NonMovingMark.h"
#include <string.h> // for memmove()
@@ -314,52 +315,66 @@ threadPaused(Capability *cap, StgTSO *tso)
continue;
}
- // an EAGER_BLACKHOLE or CAF_BLACKHOLE gets turned into a
- // BLACKHOLE here.
+ // If we have a frame that is already eagerly blackholed, we
+ // shouldn't overwrite its payload: There may already be a blocking
+ // queue (see #26324).
+ if(frame_info == &stg_bh_upd_frame_info) {
+ // eager black hole: we do nothing
+
+ // it should be a black hole that we own
+ ASSERT(bh_info == &stg_BLACKHOLE_info ||
+ bh_info == &__stg_EAGER_BLACKHOLE_info ||
+ bh_info == &stg_CAF_BLACKHOLE_info);
+ ASSERT(blackHoleOwner(bh) == tso || blackHoleOwner(bh) == NULL);
+ } else {
+ // lazy black hole
+
#if defined(THREADED_RTS)
- // first we turn it into a WHITEHOLE to claim it, and if
- // successful we write our TSO and then the BLACKHOLE info pointer.
- cur_bh_info = (const StgInfoTable *)
- cas((StgVolatilePtr)&bh->header.info,
- (StgWord)bh_info,
- (StgWord)&stg_WHITEHOLE_info);
-
- if (cur_bh_info != bh_info) {
- bh_info = cur_bh_info;
+ // first we turn it into a WHITEHOLE to claim it, and if
+ // successful we write our TSO and then the BLACKHOLE info pointer.
+ cur_bh_info = (const StgInfoTable *)
+ cas((StgVolatilePtr)&bh->header.info,
+ (StgWord)bh_info,
+ (StgWord)&stg_WHITEHOLE_info);
+
+ if (cur_bh_info != bh_info) {
+ bh_info = cur_bh_info;
#if defined(PROF_SPIN)
- NONATOMIC_ADD(&whitehole_threadPaused_spin, 1);
+ NONATOMIC_ADD(&whitehole_threadPaused_spin, 1);
#endif
- busy_wait_nop();
- goto retry;
- }
+ busy_wait_nop();
+ goto retry;
+ }
#endif
-
- IF_NONMOVING_WRITE_BARRIER_ENABLED {
- if (ip_THUNK(INFO_PTR_TO_STRUCT(bh_info))) {
- // We are about to replace a thunk with a blackhole.
- // Add the free variables of the closure we are about to
- // overwrite to the update remembered set.
- // N.B. We caught the WHITEHOLE case above.
- updateRemembSetPushThunkEager(cap,
- THUNK_INFO_PTR_TO_STRUCT(bh_info),
- (StgThunk *) bh);
+ ASSERT(bh_info != &stg_WHITEHOLE_info);
+
+ IF_NONMOVING_WRITE_BARRIER_ENABLED {
+ if (ip_THUNK(INFO_PTR_TO_STRUCT(bh_info))) {
+ // We are about to replace a thunk with a blackhole.
+ // Add the free variables of the closure we are about to
+ // overwrite to the update remembered set.
+ // N.B. We caught the WHITEHOLE case above.
+ updateRemembSetPushThunkEager(cap,
+ THUNK_INFO_PTR_TO_STRUCT(bh_info),
+ (StgThunk *) bh);
+ }
}
- }
- // zero out the slop so that the sanity checker can tell
- // where the next closure is. N.B. We mustn't do this until we have
- // pushed the free variables to the update remembered set above.
- OVERWRITING_CLOSURE_SIZE(bh, closure_sizeW_(bh, INFO_PTR_TO_STRUCT(bh_info)));
+ // zero out the slop so that the sanity checker can tell
+ // where the next closure is. N.B. We mustn't do this until we have
+ // pushed the free variables to the update remembered set above.
+ OVERWRITING_CLOSURE_SIZE(bh, closure_sizeW_(bh, INFO_PTR_TO_STRUCT(bh_info)));
- // The payload of the BLACKHOLE points to the TSO
- RELEASE_STORE(&((StgInd *)bh)->indirectee, (StgClosure *)tso);
- SET_INFO_RELEASE(bh,&stg_BLACKHOLE_info);
+ // The payload of the BLACKHOLE points to the TSO
+ RELEASE_STORE(&((StgInd *)bh)->indirectee, (StgClosure *)tso);
+ SET_INFO_RELEASE(bh,&stg_BLACKHOLE_info);
- // .. and we need a write barrier, since we just mutated the closure:
- recordClosureMutated(cap,bh);
+ // .. and we need a write barrier, since we just mutated the closure:
+ recordClosureMutated(cap,bh);
- // We pretend that bh has just been created.
- LDV_RECORD_CREATE(bh);
+ // We pretend that bh has just been created.
+ LDV_RECORD_CREATE(bh);
+ }
frame = (StgClosure *) ((StgUpdateFrame *)frame + 1);
if (prev_was_update_frame) {
=====================================
testsuite/tests/ghci-wasm/T26431.hs
=====================================
@@ -0,0 +1,35 @@
+import Control.Exception
+import Control.Monad.IO.Class
+import Data.Maybe
+import GHC
+import GHC.Plugins
+import GHC.Runtime.Interpreter
+import System.Environment.Blank
+
+main :: IO ()
+main = do
+ [libdir] <- getArgs
+ defaultErrorHandler defaultFatalMessager defaultFlushOut $
+ runGhc (Just libdir) $
+ do
+ dflags0 <- getSessionDynFlags
+ let dflags1 =
+ dflags0
+ { ghcMode = CompManager,
+ backend = interpreterBackend,
+ ghcLink = LinkInMemory
+ }
+ logger <- getLogger
+ (dflags2, _, _) <-
+ parseDynamicFlags logger dflags1 $
+ map noLoc ["-package", "ghc"]
+ _ <- setSessionDynFlags dflags2
+ addTarget =<< guessTarget "hello.hs" Nothing Nothing
+ _ <- load LoadAllTargets
+ setContext
+ [ IIDecl $ simpleImportDecl $ mkModuleName "Prelude",
+ IIDecl $ simpleImportDecl $ mkModuleName "Main"
+ ]
+ hsc_env <- getSession
+ fhv <- compileExprRemote "main"
+ liftIO $ evalIO (fromJust $ hsc_interp hsc_env) fhv
=====================================
testsuite/tests/ghci-wasm/T26431.stdout
=====================================
@@ -0,0 +1 @@
+main = putStrLn "hello world"
=====================================
testsuite/tests/ghci-wasm/all.T
=====================================
@@ -10,3 +10,11 @@ test('T26430', [
extra_hc_opts('-L. -lT26430B')]
, compile_and_run, ['']
)
+
+test('T26431', [
+ extra_files(['../../../.gitlab/hello.hs']),
+ extra_hc_opts('-package ghc'),
+ extra_run_opts(f'"{config.libdir}"'),
+ ignore_stderr]
+, compile_and_run, ['']
+)
=====================================
utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cc.hs
=====================================
@@ -11,7 +11,6 @@ module GHC.Toolchain.Tools.Cc
, compileC
, compileAsm
, addPlatformDepCcFlags
- , checkC99Support
) where
import Control.Monad
@@ -51,12 +50,8 @@ findCc archOs llvmTarget progOpt = do
cc1 <- ignoreUnusedArgs cc0
cc2 <- ccSupportsTarget archOs llvmTarget cc1
checking "whether Cc works" $ checkCcWorks cc2
- cc3 <- oneOf "cc doesn't support C99" $ map checkC99Support
- [ cc2
- , cc2 & _ccFlags %++ "-std=gnu99"
- ]
- checkCcSupportsExtraViaCFlags cc3
- return cc3
+ checkCcSupportsExtraViaCFlags cc2
+ return cc2
checkCcWorks :: Cc -> M ()
checkCcWorks cc = withTempDir $ \dir -> do
@@ -88,17 +83,6 @@ ccSupportsTarget archOs target cc =
checking "whether Cc supports --target" $
supportsTarget archOs _ccProgram checkCcWorks target cc
-checkC99Support :: Cc -> M Cc
-checkC99Support cc = checking "for C99 support" $ withTempDir $ \dir -> do
- let test_o = dir </> "test.o"
- compileC cc test_o $ unlines
- [ "#include <stdio.h>"
- , "#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L"
- , "# error \"Compiler does not advertise C99 conformance\""
- , "#endif"
- ]
- return cc
-
checkCcSupportsExtraViaCFlags :: Cc -> M ()
checkCcSupportsExtraViaCFlags cc = checking "whether cc supports extra via-c flags" $ withTempDir $ \dir -> do
let test_o = dir </> "test.o"
=====================================
utils/ghc-toolchain/src/GHC/Toolchain/Tools/Cpp.hs
=====================================
@@ -19,7 +19,7 @@ import GHC.Toolchain.Prelude
import GHC.Toolchain.Program
import GHC.Toolchain.Tools.Cc
-import GHC.Toolchain.Utils (withTempDir, oneOf, expectFileExists)
+import GHC.Toolchain.Utils (withTempDir, expectFileExists)
newtype Cpp = Cpp { cppProgram :: Program
}
@@ -160,13 +160,7 @@ findJsCpp progOpt cc = checking "for JavaScript C preprocessor" $ do
findCmmCpp :: ProgOpt -> Cc -> M CmmCpp
findCmmCpp progOpt cc = checking "for a Cmm preprocessor" $ do
-- Use the specified CPP or try to use the c compiler
- foundCppProg <- findProgram "Cmm preprocessor" progOpt [] <|> pure (programFromOpt progOpt (prgPath $ ccProgram cc) [])
- -- Check whether the C preprocessor needs -std=gnu99 (only very old toolchains need this)
- Cc cpp <- oneOf "cc doesn't support C99" $ map checkC99Support
- [ Cc foundCppProg
- , Cc (foundCppProg & _prgFlags %++ "-std=gnu99")
- ]
-
+ cpp <- findProgram "Cmm preprocessor" progOpt [] <|> pure (programFromOpt progOpt (prgPath $ ccProgram cc) [])
cmmCppSupportsG0 <- withTempDir $ \dir -> do
let conftest = dir </> "conftest.c"
writeFile conftest "int main(void) {}"
@@ -181,14 +175,9 @@ findCmmCpp progOpt cc = checking "for a Cmm preprocessor" $ do
findCpp :: ProgOpt -> Cc -> M Cpp
findCpp progOpt cc = checking "for C preprocessor" $ do
-- Use the specified CPP or try to use the c compiler
- foundCppProg <- findProgram "C preprocessor" progOpt [] <|> pure (programFromOpt progOpt (prgPath $ ccProgram cc) [])
- -- Check whether the C preprocessor needs -std=gnu99 (only very old toolchains need this)
- Cc cpp2 <- oneOf "cc doesn't support C99" $ map checkC99Support
- [ Cc foundCppProg
- , Cc (foundCppProg & _prgFlags %++ "-std=gnu99")
- ]
+ cpp <- findProgram "C preprocessor" progOpt [] <|> pure (programFromOpt progOpt (prgPath $ ccProgram cc) [])
-- Always add the -E flag to the CPP, regardless of the user options
- let cppProgram = addFlagIfNew "-E" cpp2
+ let cppProgram = addFlagIfNew "-E" cpp
return Cpp{cppProgram}
--------------------------------------------------------------------------------
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/81b7bea21aede1409cba6e24b82d16…
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/81b7bea21aede1409cba6e24b82d16…
You're receiving this email because of your account on gitlab.haskell.org.
1
0
30 Sep '25
Rodrigo Mesquita pushed new branch wip/romes/26461 at Glasgow Haskell Compiler / GHC
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/tree/wip/romes/26461
You're receiving this email because of your account on gitlab.haskell.org.
1
0